Search code examples
angularjsexpresssingle-page-applicationangular-resource2-way-object-databinding

AngularJS $resource returns empty object and doesn't update with data


I have a basic get/post api right now with AngularJS and Express/Node. I'm trying to make a SPA with angular where I can add, get, and delete boards (basically like post-it notes for the web). Every time a button is clicked, it fires $scope.addBoard, which is a $resource object that makes a POST request.

It fires alright, but it returns an empty object that updates the HTML automatically with empty data only. If I want the board populated with information, I have to do a manual refresh of the whole page. I tried incorporating a call back and using a promise, but I can't get either option to work. Is there a way I can get the HTML to update automatically with the full data after the POST request is made the angular way??

services.js

  krelloApp.factory('Boards', ['$resource', function($resource) {

  return $resource('api/boards/:id', {}, {
    get: {method: 'GET', isArray: true},
    add: {method: 'POST', transformResponse: []}
  });

}]);

controller.js

krelloApp.controller('boardController', ['$scope', '$resource', '$location', '$http', 'Boards',
function($scope, $resource, $location, $http, Boards) {

  // Get all boards
  $scope.boards = Boards.get();

  // Add board
  $scope.addBoard = function() {
    // Boards.add().then(function(response) {
    //   $scope.boards.push(response);
    // })
    // Boards.add(function(response) {
    //   $scope.boards.push(response)
    // });
    $scope.boards.push(Boards.add());
  };

}]);

API Route for POST:

  app.post('/api/boards', isLoggedIn, function(req, res) {
    // Add new board to user
    // May need more posts to add lists and stuff
    User.findOne({ _id: req.user._id }, function(err, user) {
      if (err) {
        return res.send(err);
      };
      newBoard = user.generateBoard('Extra Board');
      newList = user.generateList('Extra List');
      newCard = user.generateCard('Extra Card', 'Card Description');
      newList.cards.push(newCard);
      newBoard.lists.push(newList);
      user.boards.push(newBoard);

      user.save(function(err) {
        if (err) {
          throw err;
        };
      });

      console.log('Success POST');
      console.log('Added Board to user: ' + req.user.local.email);
      res.json(req.user.boards)
    });
  });

html:

<div class="row">
  <div class="col-xs-12 col-md-3">
    <div class="btn btn-success" ng-click="addBoard()">
      <span class="fa fa-plus-square"></span>
    </div>
  </div>
</div>

<div class="row">
  <div class="col-xs-12 col-md-3" ng-repeat="board in boards">
    <h1 class="jumbotron">{{ board.title }}</h1>
  </div>
</div>

I got a picture below too. Each board automatically generates a 'title' of 'extra board' that should show when it's generated. Only problem is that the title/data only shows after I manually refresh the whole page. When I click the green button to addBoard, it only gives me an empty board.

enter image description here Picture 2: Really odd because it actually shows that the response contains the data, but Angular isn't populating it for some reason.

Firebug Network

Final Edit (Answer):

Thanks for the help guys. For anybody with the same problem, this is what I changed to fix it:

In services.js, remove transformResponse so it looks like add:{method: 'POST'}.

In the API POST route, change the bottom line where it says res.json(req.user.boards) to res.json(newBoard);


Solution

  • I normally use the second commented out method with the callback. If you use it like this what do you get?

    Boards.add({}, function(response) {
      $scope.boards.push(response)
    }, function(error){
      console.log(error);
    });