Monty Monro
Monty Monro

Reputation: 613

Angularjs: accessing scope variable array and calculating average

sorry if the question is a little abstract from the title. I will try to explain it here and supply a Gist with relevant code.

I have a JSON api which I grab through AngularJS. This is basically a project which has several tasks. I want to go through the tasks in my $scope.projects variable (in my projects controller) and get all the 'progress' values in each task. Then I want calculate the average of them to give the overall progress for the project itself and assign it to a $scope variable to be used in my template.

I cant seem to get access to the tasks array no matter what I try and I have no idea why. So i thought asking here for some advice might be a good option. Any help would be greatly appreciated.

Gist: https://gist.github.com/Tasemu/8002741

JS

App.controller('ProjectCtrl', ['$scope', 'Project', 'Task', '$routeParams', '$location', function($scope, Project, Task, $routeParams, $location) {

    $scope.updateProjects = function() {
        if (!$routeParams.id) {
            Project.query(function(data) {
            $scope.projects = data;
            });
        } else {
            $scope.projects = Project.get({id: $routeParams.id})
        }
    };

    $scope.deleteProject = function(project) {
        Project.delete({id: project.id}, function() {
            $scope.updateProjects({id: project.id});
            $location.path('/');
        });
    };

    $scope.deleteTask = function(task) {
        Task.delete({id: task.id}, function() {
            $scope.updateProjects({id: task.id});
        });
    };

    $scope.updateProject = function(formData) {
        $scope.projects.name = formData.name;
        $scope.projects.description = formData.description;
        $scope.projects.client = formData.client;
        $scope.projects.due = formData.due;
        $scope.projects.$update({id: formData.id}, function() {
            $location.path('/');
        });
    };

    $scope.saveProject = function(project) {
        Project.save({}, project, function() {
            $location.path('/');
        });
    };

    $scope.updateProjects();

    $scope.progs = [];

    for (var i = 0; i > $scope.projects.tasks.length; i++) {
    progs.push($scope.projects.tasks.array[i].progress);
    };

    }]);

JSON

{
  id: 1,
  name: "Project 1",
  description: "this project",
  client: "monty",
  due: "2013-12-15",
  tasks: [
    {
      id: 2,
      name: "Task 2",
      progress: 22,
      project_id: 1,
      created_at: "2013-12-17T03:08:53.849Z",
      updated_at: "2013-12-17T05:06:31.602Z"
    },
    {
      id: 1,
      name: "Task 1",
      progress: 75,
      project_id: 1,
      created_at: "2013-12-17T03:08:53.845Z",
      updated_at: "2013-12-17T05:25:50.405Z"
    }
  ],
  created_at: "2013-12-17T03:08:53.719Z",
  updated_at: "2013-12-17T06:57:52.699Z"
}

JS

App.factory('Project', function($resource) {
return $resource(
    '/api/v1/projects/:id.json',
    {id: '@id'},
    {
        update: {
            method: 'PUT',
            params: { id: '@id' },
            isArray: false
        }
    }
);
});

If you need any more information please don't hesitate to ask!

Upvotes: 1

Views: 4964

Answers (2)

kubuntu
kubuntu

Reputation: 2535

You are trying to access project.tasks before it is ready. I suggest you wrap the calculation in a function and call it in the success callback when retrieving/updating projects.

$scope.updateProjects = function() {
    if (!$routeParams.id) {
      Project.query(function(data) {
        $scope.projects = data;
        $scope.calculateTasks();
      });
    } else {
        $scope.projects = Project.get({id: $routeParams.id})
    }
};

...
$scope.calculateTasks = function () {
    $scope.progs = [];
    for (var i = 0; i > $scope.projects.tasks.length; i++) {
        $scope.progs.push($scope.projects.tasks.array[i].progress);
    };
}
$scope.updateProjects();

Upvotes: 0

peaceman
peaceman

Reputation: 2609

You have to delay the progress calculation (line 46 to 48 in project_controller.js) until your data is fully loaded. Extract the calculation into a new method and call this new method in the callback on line 6 and in a new callback you have to create at line 9.

Upvotes: 1

Related Questions