8829

Using AngularJS's $resource to query a database

Question:

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:<img alt="enter image description here" class="b-lazy" data-src="https://i.stack.imgur.com/pNMTQ.png" data-original="https://i.stack.imgur.com/pNMTQ.png" src="https://etrip.eimg.top/images/2019/05/07/timg.gif" /> 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>

Answer1:

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 <a href="http://docs.angularjs.org/api/ngResource.%24resource" rel="nofollow">docs</a> 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 }); });

Answer2:

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

<a href="http://docs.angularjs.org/api/ngResource" rel="nofollow">http://docs.angularjs.org/api/ngResource</a>.$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).

Answer3:

The "Angular" way to solve this problem is by using the <a href="http://docs.angularjs.org/api/ng.%24q" rel="nofollow">$q library</a> 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; }); }

Recommend

  • How-to: short-circuiting inverted ternary operator implemented in, e.g. C#? Does it matter?
  • Subreport causing infinite loop
  • When try to execute a cgi script, get the error: “[WinError 193] %1 is not a valid Win32 application
  • chrome devtools inconsistency array length
  • Cannot use an @IdClass attribute for a @ManyToOne relationship
  • Set indent on view in Zend Framework
  • Disable check for override in gcc
  • Fatal error on Windows XP when compiled with XP Targeting in Visual Studio 2015
  • XGBOOST - DMATRIX
  • Getting EOFError along with exceptions when using ftplib
  • Using an STL Iterator without initialising it
  • SQL: Getting the physical size of a subset of a table
  • Criterion causing memory consumption to explode, no CAFs in sight
  • How do I remove all but some records based on a threshold?
  • Using $compile in a directive triggers AngularJS infinite digest error
  • Updating Dojo provide
  • How do I get the list of bad records that didn't load in Bigquery?
  • Web.config system.webserver errors
  • How to generate and display a QR Code in ionic 2
  • TextToSpeech.setEngineByPackageName() triggers NullPointerException
  • Sequential (transactional) API calls in angular 4 with state management
  • Sencha Touch 2.0 Controller refs attribute not working?
  • Atlas images wrong size on iPad iOS 9
  • Is it possible to access block's scope in method?
  • Function pointer “assignment from incompatible pointer type” only when using vararg ellipsis
  • Warning: Can't call setState (or forceUpdate) on an unmounted component
  • 0x202A in filename: Why?
  • bootstrap to use multiple ng-app
  • How to get icons for entities from eclipse?
  • File not found error Google Drive API
  • Turn off referential integrity in Derby? is it possible?
  • JaxB to read class hierarchy
  • Busy indicator not showing up in wpf window [duplicate]
  • Running Map reduces the dimensions of the matrices
  • Reading document lines to the user (python)
  • Binding checkboxes to object values in AngularJs
  • Python/Django TangoWithDjango Models and Databases
  • Net Present Value in Excel for Grouped Recurring CF
  • jQuery Masonry / Isotope and fluid images: Momentary overlap on window resize
  • How to load view controller without button in storyboard?