You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.6 KiB

MEAN Stack Part 2

Lesson Objectives

  1. Create a function to get all todos
  2. On page load, show all todos
  3. After creating a new todo, refresh list of todos
  4. Clicking on a todo toggles it complete/incomplete
  5. Create a delete button
  6. Edit the Todo

Create a function to get all todos

public/js/app.js:

this.getTodos = function(){
    $http({
        method:'GET',
        url: '/todos',
    }).then(function(response){
        console.log(response);
    }, function(){
        console.log('error');
    });
};

this.getTodos(); //call immediately once controller is instantiated to test

On page load, show all todos

  1. create controller variable set to this
  2. set property one controller when ajax succeeds
  3. call getTodos during controller instantiation

public/js/app.js:

app.controller('MyController', ['$http', function($http){
    this.description = null;
    this.complete = false;
    const controller = this; //create controller var

    //...farther down the page
    this.getTodos = function(){
        $http({
            method:'GET',
            url: '/todos',
        }).then(function(response){
            controller.todos = response.data; //set value on success
        }, function(){
            console.log('error');
        });
    };

    this.getTodos(); //call immediately once controller is instantiated
}]);

public/index.html:

<ul>
    <li
        ng-repeat="todo in ctrl.todos"
        ng-class="(todo.complete)?'complete':''">
            {{todo.description}}
    </li>
</ul>
  1. mkdir public/css
  2. touch public/css/app.css

public/css/app.css:

.complete {
    text-decoration: line-through;
}

public/index.html:

<link rel="stylesheet" href="/css/app.css">

After creating a new todo, refresh list of todos

public/js/app.js:

$http({
    method:'POST',
    url: '/todos',
    data: {
        description: this.description,
        complete: this.complete
    }
}).then(function(response){
    controller.getTodos(); //get all todos when new element is added
}, function(){
    console.log('error');
});

Clicking on a todo toggles it complete/incomplete

public/index.html:

<ul>
    <li
        ng-class=" (todo.complete) ? 'complete' : 'incomplete' "
        ng-repeat="todo in ctrl.todos">
            <span ng-click="ctrl.toggleTodoComplete(todo);">{{todo.description}}</span>
    </li>
</ul>

public/js/app.js:

this.toggleTodoComplete = function(todo){
    let newCompleteValue;
    if(todo.complete === true){
        newCompleteValue = false;
    } else {
        newCompleteValue = true;
    }

    $http({
        method:'PUT',
        url: '/todos/' + todo._id,
        data: {
            description: todo.description,
            complete: newCompleteValue
        }
    }).then(function(response){
        controller.getTodos();
    }, function(){
        console.log('error');
    });
}

Create a delete button

In the <li> for each todo:

<button ng-click="ctrl.deleteTodo(todo)">Delete This Todo</button>
this.deleteTodo = function(todo){
    $http({
        method:'DELETE',
        url: '/todos/' + todo._id
    }).then(
        function(response){
            controller.getTodos();
        },
        function(error){

        }
    );
}

Edit the Todo

In the <li> for each todo:

<form ng-submit="ctrl.editTodo(todo);">
    <input type="text" ng-model="ctrl.updatedDescription" placeholder="description" />
    <input type="submit" value="Update Description">
</form>
this.editTodo = function(todo){
    $http({
        method:'PUT',
        url: '/todos/' + todo._id,
        data: {
            description: this.updatedDescription,
            complete: todo.complete
        }
    }).then(
        function(response){
            controller.getTodos();
        },
        function(error){

        }
    );
}

To hide extra edit fields:

this.indexOfEditFormToShow = null;
<a
    ng-if="$index !== ctrl.indexOfEditFormToShow"
    href="#"
    ng-click="ctrl.indexOfEditFormToShow = $index">
        Edit This Todo
</a>
<form ng-if="$index === ctrl.indexOfEditFormToShow" ng-submit="ctrl.editTodo(todo);">
controller.indexOfEditFormToShow = null; //add this inside success callback to editTodo $http request

Fix styling of line-through:

<li ng-repeat="todo in ctrl.todos">
    <span
        ng-class=" (todo.complete) ? 'complete' : '' "
        ng-click="ctrl.toggleTodoComplete(todo)">{{todo.description}}</span>