Stack Overflow is a community of 4.7 million programmers, just like you, helping each other.

Join them; it only takes a minute:

Sign up
Join the Stack Overflow community to:
  1. Ask programming questions
  2. Answer and help your peers
  3. Get recognized for your expertise

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);

share|improve this question
    
you probably should be using the first commented out form, but in the .then, use response.data rather than just response. – Claies Jan 16 at 2:10
    
Not sure if I'm missing something, but the promise isn't registering I think. Gives me error saying it's not a function. Error: Boards.add(...).then is not a function $scope.addBoard@127.0.0.1:8000/static/scripts/controller.js:9:5 Tried: $scope.addBoard = function() { Boards.add().then(function(response) { $scope.boards.push(response.data); console.log("response: " + response) console.log("response.data: " + response.data) }) }; – Kyle Truong Jan 16 at 2:16
    
I just noticed you have transformResponse : [] on your post. That is going to disable the default behavior of parsing the response into a JSON object, which is what you are trying to consume. What happens if you remove this parameter? – Claies Jan 16 at 2:24
    
when I take it out, it still populates a board (empty), but it gives me a long error with a link. Description of the error: This error occurs when the $resource service expects a response that can be deserialized as an array but receives an object, or vice versa. By default, all resource actions expect objects, except query which expects arrays. – Kyle Truong Jan 16 at 2:34
1  
What happens if you push the initial $resource object to an array? $scope.boards=[]; $scope.boards.push(Boards.get()); – georgeawg Jan 16 at 3:54
up vote 1 down vote accepted

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);
});
share|improve this answer
    
Doesn't give me any errors, though it still is giving me empty boards that only populate with data if I refresh manually. – Kyle Truong Jan 16 at 2:38
1  
Do you control the server as well? If so can you have it return an array? Another thing to try is adding isArray: false.. I'm not sure if it works with a POST action though. – Brian Baker Jan 16 at 3:49
    
Hallelujah, thanks for the help. I changed the bottom line of my POST API to res.json(newBoard), my $resource add method to: add: {method: 'POST'}, and stuck with the same idea for the controller: $scope.boards.push(Boards.add()); – Kyle Truong Jan 16 at 4:01

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.