user2656127
user2656127

Reputation: 665

Populate an array with data from database (Angular + PHP/MySQL)

I have a simple to-do app I'm working on, which is using Angular and then PHP/MySQL for the backend.

I now have a simple app that works, where I can add new todos, and add the "percentage completed" per day to the Database, using a simple $http post.

However now what I'm looking to do is, populate the $scope.historicalDailyPercentages array, with data from the database.

At the start of the script, I init the object like so:

$scope.historicalDailyPercentages = []; //TODO, this should be initialised with data from the database.

I understand I'll need to have some sort of $http get loop in there, to check for the data and fill the object, but I'm a little unclear on how to get started there.

The entire goalzy.js script is below for reference. Thanks in advance!

angular.module('goalzy', [])

.config(['$httpProvider', function($httpProvider) {
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/json; charset=utf-8';
}])

.controller('TodoController', ['$scope', '$http', function($scope, $http) {

    $scope.todos = [];
    $scope.historicalDailyPercentages = []; //TODO, this should be initialised with data from the database.

    $scope.addTodo = function() {
        if ($scope.todoText != "") {
            if ($scope.todos.length < 3) {
                $scope.todos.push({
                    text: $scope.todoText,
                    done: false
                });
                $scope.todoText = '';
                //Save to DB
            } else {
                alert("You can only have 3 todos per day!");
                $scope.todoText = '';
            }
        } else {
            alert("you must write something");
        }
    };

    $scope.remaining = function() {
        var count = 0;
        angular.forEach($scope.todos, function(todo) {
            count += todo.done ? 0 : 1;
        });
        return count;
    };

    $scope.percentComplete = function() {
        var countCompleted = 0;
        angular.forEach($scope.todos, function(todo) {
            countCompleted += todo.done ? 1 : 0; //Simply calculates how many tasks have been completed
            console.log(countCompleted);
        });
        var totalCount = $scope.todos.length;
        var percentComplete = countCompleted / totalCount * 100;
        return percentComplete;
    }

    $scope.finaliseDay = function(percentComplete) {
        alert("You're finalising this day with a percentage of: " + percentComplete);
        var today = new Date();
        var alreadyPresent = $scope.historicalDailyPercentages.some(function(item) {
            return item.date.getFullYear() === today.getFullYear() &&
                item.date.getMonth() === today.getMonth() &&
                item.date.getDate() === today.getDate();
        });

        //Confirm that nothing has alreayd been posted for today
        if (!alreadyPresent) {

            // Simple POST request example (passing data)
            $http.post('/postDailyPercentage.php', {
                user_id: 1,
                percent: percentComplete,
                date: today
            }).
            success(function(data, status, headers, config) {
                // this callback will be called asynchronously
                // when the response is available
                if (data) {

                    $scope.historicalDailyPercentages.push({
                        user_id: 1,
                        percent: percentComplete,
                        date: today
                    });

                } else {
                    alert("Something went wrong" + data);
                }

            }).
            error(function(data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log("Post failure");
            });
        } else {
            alert("You're all set for today - see you tomorrow!");
        }

        //console.log($scope.historicalDailyPercentages);
    }
}]);

Upvotes: 2

Views: 3145

Answers (2)

Dan
Dan

Reputation: 10548

var TodoController = function($scope, HistoricalDailyPercentageService) {
  HistoricalDailyPercentageService.get().then(function(percentages) {
    $scope.historicalDailyPercentages = percentages;
  }, function(error) {
    alert(error);
  });
};

var HistoricalDailyPercentageService = function($http) {
  this.get = function() {
    return $http.get('yourUrl')
      .then(function(xhr) {
        var data = xhr.data;
        // Transform the data as you see fit
        return data;
      }, function(xhr) {
        // xhr contains the error message - modify this as you see fit.
        return xhr.code;
      });
  };
};

angular.module('goalzy')
  .controller('TodoController', ['$scope', 'HistoricalDailyPercentages', TodoController])
  .service('HistoricalDailyPercentageService', ['$http', HistoricalDailyPercentageService]);

I would recommend doing it this way; this will make it easier to test by taking the logic of getting the data out of your already busy controller. @RVandersteen's example will only work inside of your controller, which is fine, but it really does make your controller very busy; controllers should really only assign things to a scope, everything else should be handled in a directive (for example, binding events to methods) or a service/factory/provider (for business logic).

After you have finished up your code, could you post on CodeReview? There's a few improvements I could suggest but they are merely review-based things and not appropriate for the scope of this question.

It's worth noting by the way that because I am using then in the controller I must use then in the service, too. If I use success in the service then my changes will not be reflected when I call then in the controller.

Upvotes: 1

RVandersteen
RVandersteen

Reputation: 2137

To populate that object with an $http.get you can do it as follows:

function getHistoricalDataSuccess(data) {
  $scope.historicalDailyPercentages = data;
}

function getHistoricalDataError(error) {
  //handle the error
}

$http.get('path/to/api')
.success(getHistoricalDataSuccess)
.error(getHistoricalDataError);

Upvotes: 2

Related Questions