0

I've created an API that works via a url, built on node.js, express.js, mongoDB and angular.js.

My API is called like this:

app.get('/api/posts/:query', api.postsQuery);

So if I type localhost:3000/api/posts/<whateverquery>, mongoDB spits out all the pertinent JSON to my browser, so this is working just fine.

However, I'm trying to link this up to my Angular front-end, and it's causing issues. I want the user to be able to search into a form and have my database return the correct records. Here's my controller:

function indexCtrl($scope, $http, $resource) {
  $scope.itemSearch = $resource('http://localhost\\:3000/api/posts/:query', 
    {query:''}, {get:{method:'JSONP'}});

  $scope.doSearch = function(){
    $scope.posts = $scope.itemSearch.get({query:$scope.searchTerm});
    console.log($scope.posts[1]) // returns undefined
  }
}

My issue is that when I run $scope.doSearch, I see the query in Chrome's resources panel like this:enter image description here so the correct data is indeed being loaded, but it's not attaching itself to $scope.posts.

I have the feeling this might be because I need a callback function; I tried using callback: JSON_CALLBACK but that messes up my query/API (because it adds a ?callback=...to the end of the $resource call and this breaks the query).

Any ideas on what I can do here to get it working? Is the problem a lack of a callback? Perhaps I can add some regex to the app.get call, after :query to allow any wildcards afterward>

3 Answers 3

2

Add the callback to your $resource call:

$scope.doSearch = function(){
    $scope.itemSearch.get({query:$scope.searchTerm}, function(data){
        $scope.posts = data.posts;
        console.log($scope.posts[1]);
    });
};

Notice in the docs that they utilize the callback:

var User = $resource('/user/:userId', {userId:'@id'});
User.get({userId:123}, function(u, getResponseHeaders){
    u.abc = true;
    u.$save(function(u, putResponseHeaders) {
    //u => saved user object
    //putResponseHeaders => $http header getter
    });
});
Sign up to request clarification or add additional context in comments.

1 Comment

While the other answers had callbacks, yours had the idea to wait until the callback to make $scope.posts=data which got it working. A slight correction though, if you look at the screenshot in my original question, the post data is returned in data.posts so I needed to make $scope.posts = data.posts to get it working. Thanks!
1

Based on a looksie through the docs (and knowing AngularJS does everything asynchronously normally) it looks like the code below should work

$scope.doSearch = function(){
    $scope.posts = $scope.itemSearch.get({query:$scope.searchTerm}, function(){
        console.log($scope.posts[1]) // hopefully is something
    });
  }

http://docs.angularjs.org/api/ngResource.$resource

Since things are done asynchronously (to avoid blocking/waiting/pausing) there's usually either a callback or a promise for anything that is likely to take time (network calls).

Comments

1

The "Angular" way to solve this problem is by using the $q library for promises.

function indexCtrl($scope, $resource, $q) {
  var defer = $q.defer();

  var resource = $resource('http://localhost\\:3000/api/posts/:query', {query:''}, {get:{method:'JSONP'}});

  resource.get({query:'mySearchQuery'}, defer.resolve);

  defer.promise.then(function(data) {
    $scope.posts = data;
  });
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.