Nodejs not sending response to Angular? - angularjs

I have a doozy that I can't figure out whats going on.
In Mongo, I do a document.find(), which returns an array of object/s - All good.
I'm then trying to send on two objects back to the Angular Controller, the document object/s and the length of the array of objects.
Code:
function loadConnections(req, res) {
getConnections(req.user)
.then(function(results){
console.log('here');
console.log(results);
console.log(results.length);
var returnObject = {}
returnObject.count = results.length;
//returnObject.results = results[0]; // PROBLEM LINE
res.status(200).send(returnObject);
});
}
Problem I'm facing. In this scenario, it returns an array with 1 object. The array looks like:
[{id: XXX, test: YYY, test1: ZZZ}]
These have been what I've tried and tested:
returnObject.results = results[0].id; // works
returnObject.results = results[0].test; // works
returnObject.results = results[0].test1; //works
returnObject.results = results[0]; // doesn't work
returnObject.results = results; //doesn't work
But if I try to pass the entire object or the entire array, it hits an issue and doesn't send the response to the controller.
Any thoughts?

If you are using express, try to do a
res.send(200, returnObject);
or
res.json(200, returnObject);
that should do the trick!

Personally I would just calculate the length of the array after it arrives in my Angular client, rather than on the server. However, you should be able to accomplish what you're trying to do by doing this:
var returnObject = {
'count': results.length,
'results': results
};
res.json(returnObject);
Here's the doc: http://expressjs.com/en/api.html#res.json
Also just for general troubleshooting, the first thing you want to do is figure out where the inconsistency is starting. Does the data look right on the server before you send the response? Does the data look right on the client when your API handler receives the response? (I'm assuming $resource, or maybe you're using $http). So add a line like this just before you send the response from the server, and then add a similar line just after you receive the response in the client:
console.log(JSON.stringify(returnObject, null, 2));

Turns out it was my lodash library. I was using _.pluck and somewhere along the way, it's stopped working. Had to update it to _.map.

Related

Post promise returns ids that are needed for another post promise

I am using http post methods to get the data from an endpoint to populate a table. I first need to get the id of the recipients, and subsequently I need to use the Id of these recipients to grab an object belonging to the recipient from another endpoint.
I have a http post that returns a promise. Using .then, I store these id numbers which I store on a javascript array. I then need to make one http post for each id on the array that will return another promise. Not sure if this is the best way to go:
getRecipients = httpService.doPost("/search", [], {userId:"test"});
getRecipients.then(function(recipientData){
vm.recipients = recipientData.data.recipients;
}).then(function(){
for(x in vm.recipients)
{
httpService.doPost("/searchObjects", [], vm.recipients[x].id)
.then(function(){
//store each object returned on another array here....
});
}
});
NOTE: doPost(endpoint, not used, parameters to do the search)
With the above method, the problem is that the for loop will not wait for the then and will move to the next iteration once the doPost has been called.
I guess I can use bluebird, but not sure if that would be the best way to go in here, and if so, how should it be done (note that this is server side javascript so require is not available per say unless I use require.js)?
If I'm understanding you correctly, you're looking for something like this:
getRecipients = httpService.doPost("/search", [], {userId:"test"});
getRecipients.then(function(recipientData){
vm.recipients = recipientData.data.recipients;
var promises = [];
for (x in vm.recipients) {
promises.push(httpService.doPost("/searchObjects", [], vm.recipients[x].id));
}
// in this case $q.all waits for all of the requests to finish
// then gives the responses
$q.all(promises).then(function(responses) {
// responses is an array of the responses
// from each request in the promise array
});
});

Restangular getList() does not return array of list items

I try to use Restangular to handle calls to my restful API.
Here is my code:
var baseStories = Restangular.all('stories/all');
baseStories.getList().then(function (stories) {
console.log(stories);
})
The console.log shows the full restangularized array instead of an array of stories as I'd expect.
I use the RestangularProvider.addResponseInterceptor from the docs to unwrap the response data.
Has anyone an idea what I'm missing?
Edit:
Below is a screenshot of the console.log output from the code above. I see two stories (which is correct) and a bunch of Restangular methods. Is it possible to only get the stories?
Actually addResponseInterceptor must return restangularized element. It is written in the documentation:
https://github.com/mgonto/restangular#addresponseinterceptor
In order to get clean response you have to call plain() method on the response element:
var baseStories = Restangular.all('stories/all');
baseStories.getList().then(function (response) {
$scope.stories = response.plain();
})

Adding a promise to browser.driver.wait not working in protractor

I am using node-resemble image comparison library to compare two images in a protractor test. Node-resemble returns a promise which resolves with comparison data. I want protractor to wait till the results are available.
I have tried using browser.driver.wait to achieve this, but somehow it is not working. Here's the code I am using for returning a promise to browser.driver.wait:
var compareImage = function(path1, path2) {
var deferred = protractor.promise.defer();
var img1 = fs.readFileSync(path1);
var img3 = fs.readFileSync(path2);
resemble(img1).compareTo(img3).onComplete(function(data) {
console.log(data);
deferred.fulfill(data);
});
return deferred.promise;
};
And this is how I am using it:
var prom = compareImage(path1, path2);
browser.driver.wait(prom, 3000).then(function(data) {
console.log(data);
expect(data.misMatchPercentage).toBe('0.00');
});
I have read the documentation and have tried to do it the way it is described, but somehow it is not working. None of the two console.log are logging the data to console. Here is what the documentation says:
Example: Suppose you have a function, startTestServer, that returns a promise for when a server is ready for requests. You can
block a WebDriver client on this promise with: var started =
startTestServer(); driver.wait(started, 5 * 1000, 'Server should start
within 5 seconds'); driver.get(getServerUrl());
It seems like there is something I am missing out. Any help is appreciated!
You have used browser.driver.wait.
Instead use browser.wait and see how it works

Issues with single-requests in Restangular

I'm having a slight issue with my ability to consume REST data retrieved via Restangular in an angular controller. I have the following code which works fine for a list of accounts:
var baseAccounts = Restangular.all('accounts');
baseAccounts.getList().then(function(accounts) {
$scope.accounts = accounts;
});
This works perfectly for a list. I use similar syntax for a single account:
var baseAccount = Restangular.one('accounts');
baseAccount.getList(GUID).then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
I am using ng-repeat as the handling directive for my first request. I am attempting to bind with {{ account.name }} tags for the single request, but it does not seem to display any data despite the request being made properly. GUID is the parameter I must pass in to retrieve the relevant record.
I have combed through Restangular docs and it seems to me like I am composing my request properly. Any insight would be greatly appreciated.
EDIT: I've tried all of the solutions listed here to no avail. It would seem Restangular is submitting the correctly structured request, but when it returns it through my controller it shows up as just a request for a list of accounts. When the response is logged, it shows the same response as would be expected for a list of accounts. I do not believe this is a scoping issue as I have encapsulated my request in a way that should work to mitigate that. So, there seems to be a disconnect between Request -> Restangular object/promise that populates the request -> data-binding to the request. Restangular alternates between returning the array of accounts or undefined.
Have you looked at:
https://github.com/mgonto/restangular#using-values-directly-in-templates
Since Angular 1.2, Promise unwrapping in templates has been disabled by default and will be deprecated soon.
Try:
$scope.accounts = baseAccounts.getList().$object;
try:
var baseAccount = Restangular.one('accounts', GUID);
baseAccount.get().then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
The problem here is that it's expecting an array to be returned. I'm assuming that you are expecting an account object. Thus we need to use the get function, intead of getList()
The one() function has a second argument that accepts an id e.g. .one('users', 1). You can take a use of it.
CODE
var baseAccount = Restangular.one('accounts', 1); //1 would be account id
baseAccount.getList('account').then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
OR
var baseAccount = Restangular.one('accounts', 1); //1 would be account id
baseAccount.all('account').getList().then(function(returnedAccount) {
$scope.currentAccount = returnedAccount;
});
For more info take look at github issue
Hope this could help you, Thanks.

Restangular data, getting into $scope for a list

Been wrestling with API stuff all day, and decided to use Restanglar. Really having issues getting the data out, and into $scope.
I understand that it won't just be the JSON that is returned from the API, and has a bunch of other internal methods etc. But when I get the data out, I can see it buried somewhere in the debugging with console.log, but I can't seem to get it into $scope to use it in my view which was working fine previously.
How can I get that data out into my $scope, and therefore my view?
Model
angular.module('horse', ['restangular'])
.config(function(RestangularProvider) {
RestangularProvider.setBaseUrl('http://url/api');
RestangularProvider.setResponseInterceptor(
function(data, operation, what) {
if (operation == 'getList') {
return data[what];
}
return data;
});
});
Controller
angular
.module('horse')
.controller("IndexController", function ($scope, Restangular) {
$scope.horse = null;
$scope.showSpinner = true;
Restangular.all('horse').getList().then(function(horse) {
$scope.horse = horse;
console.log($scope.horse);
});
});
API response
{"error":false,"horse":[{"id":"1","name":"horse 2"},{"id":"2","name":"horse 2"}]}
Edit 1
Restangular response
[Object, Object, route: "horse", getRestangularUrl: function, getRequestedUrl: function, addRestangularMethod: function, clone: function…]
Edit 2
I have also tried this - https://github.com/mgonto/restangular#using-values-directly-in-templates
$scope.horse = Restangular.all('horse').getList().$object;
Which just results in an empty array being output. I have also tried removing the setResponseInterceptor and modifying the structure of the api to result the data array directly without the meta stuff (error, etc), no joy :(
The data seems to be coming through. I notice you're using Steroids, have you checked the markup and not just the console?
Make sure you set the scope spinner to false, to ensure that the spinner is hidden when the data comes through.
$scope.ShowSpinner = false;
Assuming that what you have shown as "API response" is what's getting outputted from the console.log in your controller, it seems that all you need to do is set your scope model the the property "horse" in the response data like this:
$scope.horse = horse.horse;
Since that reads pretty oddly, you should change the param name of the .then callback to data, which would be a much more agnostic and standard param name. If you make that change you can set your horse data to your scope model from inside your callback like this:
$scope.horse = data.horse;
If I misunderstood your question let me know. Hope this is helpful.

Resources