Search code examples
javascriptangularjsangular-servicesangularjs-routing

Angular JS - variable returning undefined


I've got a simple to do application, you enter an item on the new item partial/view, which then adds a new entry onto the UI in the home page partial.

I have a service which allows me to share the data for these items/tasks between both controllers/views, the service adds data to the taskArr when the form is submitted on the new item page.

The service then has a getTasks function, which is used to access the data on the home page.

My issue is that the toDoList variable, is returning undefined, instead of the array with the nested object.

Home page HTML

<div ng-controller= "homePageCtrl">
<div class="row header">
    <div class="col-12">
        <h1>DOINGO</h1>
        <p>0 Open Tasks</p>
    </div>
</div>
<div class="row toDoList">

    <div class="row newItem"  ng-repeat ="item in toDoList">
        <div class="col-2">
            <button class="itemComplete btn"><i class="far fa-check-circle fa-2x"></i></button>
        </div>
        <div class="col-8">
            <h4>{{item.project}}</h4>
            <p>{{item.task}}.</p>
        </div>
        <div class="col-2">
            <button class="btn deleteItem"><i class="far fa-times-circle fa-2x"></i></button>
        </div>
    </div>

</div>

<div class="row addItemRow">
    <div class="col-12 text-center">
        <a href="#/newItem"><button type="button" class="btn btn addItem">
                <i class="fas fa-plus-circle fa-3x"></i>
            </button></a>
    </div>
</div>
</div>

New item HTML

    <div ng-controller="newItemCtrl">
    <div class="row header">
        <div class="col-12">
            <h1>DOINGO</h1>
        </div>
    </div>
    <div class="row addNewItem">
        <form class="form" ng-submit="addNewToDoTask()">
            <div class="row projectInput text-center">
                <div class="col-12">
                    <input type="text" ng-model = "projectInput" placeholder="Enter a project title">
                </div>
            </div>
            <div class="row taskInput text-center">
                <div class="col-12">
                    <input type="text"  ng-model = "taskInput" placeholder="Enter your task details">
                </div>
            </div>



            </div>
            <div class="buttonRow row">
                <div class="col-12 text-center">
                <a href="#/">
                  <button type="submit"
                         class="btn-lg btn-success addItemButton">
                     Add
                  </button>
        </form>
        <a href="#/"><button class="btn-lg btn-danger cancelButton">Cancel</button></a>
    </div>
    </div>
    </div>

app.module.js

var app = angular.module('ToDoListApp', ['ngRoute']);


app.config(function ($routeProvider, $locationProvider) {

    $locationProvider.hashPrefix('');

    $routeProvider

        .when("/", {
            templateUrl: "app/home/homePage.html",
        })
        .when("/newItem", {
            templateUrl: "app/newItem/newitem.html",
        })
        .otherwise({
            redirectTo: '/'
        });
});

//controller for home page

app.controller('homePageCtrl', function ($scope, newToDoTaskService) {


$scope.toDoList = newToDoTaskService.getTasks();

});

//controller for new item page
app.controller('newItemCtrl', function ($scope, newToDoTaskService) {

    $scope.addNewToDoTask = function () {
        newToDoTaskService.addTask({
            project: $scope.projectInput,
            task: $scope.taskInput,
            done: false
        });
        $scope.projectInput = "";
        $scope.taskInput = "";
    };

});

//service to persist data across views
app.service('newToDoTaskService', function () {
    var taskArr = [];
    this.getTasks = function() {
        return taskArr;
    };
    this.addTask = function(task) {
        taskArr.push(task);
    };
});


Solution

  • When the submit button is enclosed by an <a> tag, it is ignored. The <a> element changes the view before the ng-submit directive has a chance to execute.

    ERRONEOUS

    <form class="form" ng-submit="addNewToDoTask()">
    
        <!-- ... -->
    
        <div class="buttonRow row">
            <div class="col-12 text-center">
                <a href="#/">
                  <button type="submit" class="btn-lg btn-success addItemButton">
                     Add
                  </button>
    </form>
    

    Please note, while HTML5 parsers will automatically close unclosed tags, it is better to explicitly close them. It makes the code easier to understand, debug, maintain, and avoids unexpected behavior.