AngularJS $http success but not working - angularjs

i'm using angularJS and SLIM PHP restful server, the PHP service is working and actually i have already used $http.get() with no problems in this application ...
But now a strange thing is happening, i created a new function in the same way that the others, and it get .success(function(data)) with no problems, i actually can console.log(data) and it shows the right results, but when .success() finish and return, i recieve a undefined result.
ps: there is no error in browser console.
var markerOptions = [];
loadMarkers();
console.log(markerOptions);
function loadMarkers() {
$http.get('http://localhost/rest/getMarkers').success(function(response){
console.log(response);
markerOptions = response;
});
}
Console.log() inside success() return the right data
Console.log() after loadMarkers() return undefined

#MarcKline's comments are correct. Anyways, following what I think you're trying to achive by this piece of code of yours, you can assign the returned data from the ajax response to a scope variable (assuming you're using $scope), e.g $scope.markerOptions = response. You can declare markOptions as a scope variable by var $scope.markOptions = [] (...and, of course, log it by console.log($scope.markOptions) accordingly). Also, define $scope.loadMarkers = function() {...} and call it by $scope.loadMarkers()
The scope will be updated as soon as the client-side gets its ajax response.
Hope it helps your current needs in addition to a better understanding of javasciprt's async approach that some of its principles were explained to you by the comments.

Related

http.get doesn't work inside a for loop when fetching data from mongo using express

I am trying to fetch data from mongodb using express to angular inside a for loop.
I can access data inside this get instance but not outside of it. Here is my code
var daily_jobs=[];
$http.get(mongodUrl).then(function(response) {
var allMachinename = response.data;
daily_jobs=[];
for(var i = 0;i<allMachinename.length;i++){
$scope.masch_name.push({name:allMachinename[i].name,id:allMachinename[i].id,daily_jobs:[]});
$http.get(mongodUrl+'getmaschdata/'+$scope.input_id+'/'+allMachinename[i].id).then(function(jobs) {
if(jobs.data.length > 0){
daily_jobs= jobs.data;
}
console.log(daily_jobs[0].job_name);
},function(err){
console.log(err);
});
$scope.masch_name[i].daily_jobs= daily_jobs;
}
},function(err){
//console.log(err);
});
The variable daily_jobs is global, but when I want to access it outside the get function it always remain empty. How can I get that value outside of second http.get function? Any help will be appreciated. Thanks.
I couldn't get a clear picture what are you trying to achieve why are you making two http get inside a controller rather than making as a service. however to answer your question replace this
daily_jobs= jobs.data;
with
$scope.masch_name[i].daily_jobs = jobs.data;
that should work if you want to know more about this read here
Angular Share Variable betwen $http.get and controller
I will suggest you to read about services in AngularJS and $scope.apply as well for more detail

Remove $promise and $resolved from json object not working

I'm getting data from the server using $resource like this
service
.factory('rulesService', ['$resource', function ($resource) {
var systems = $resource('url');
return systems;
}]);
controller
$scope.rules= rulesService.query();
console.log($scope.rules);
The output I get is
0: Resource
1: Resource
$promise: Promise
$resolved: true
length: 2
I tried to strip $promise & $resolved using
1) angular.toJson($scope.rules)
2)JSON.stringify($scope.rules, null, 2)
Both these are returning []
Can someone help me on this
After reading your comments above, I think your problem is you use $resource wrong.
$resource will return a empty object or array, and then make the http call in the background and populate the array/object once it is complete.
This means that, at the time you console.log the object, it is actually an empty array, but since the log in the browser is pretty smart, it will update the object in the log as well, once the $resource call is done.
this is why console.log(rules[0]) is undefined, while console.log(rules) says the element exists. It didn't at the time of the log.
If you need to do further processing you have to do something like:
var rules = rulesService.query(function () {
console.log(rules[0])
})
you can also use promises instead of a callback, but either way you need to ensure the data is fully loaded
You should be able to simply iterate over the array (and ignore the extra properties). If you want a clean array you could always use a map or similar.
$scope.new_rules = $scope.rules.map(function (rule){
return rule;
})
Your problem is related to asynchronous execution and race conditions.
You're trying to refer to rules[0] before data actually arrives from the $resource.query() call.
Examples:
var rules = rulesService.query();
console.log(rules[0]); //will print nothing. the GET request hasn't been resolved yet.
rules.$promise.then(function (response) {
console.log(rules[0]); //This WILL work assuming you actually get data from the backend.
console.log(response[0]); //This will also work with the same data.
});

Value in view not updating after $promise is resolved

I have a value in my view that is not updating after a service method is called.
Here is the relevant code in the controller:
$scope.remaining = 20;
AcctService.getCurrentCount.get(calculateRemaining); //This is a $resource method
function calculateRemaining(result) {
$scope.remaining -= result;
alert($scope.remaining);
}
Here is the code for .getCurrentCount:
service.getCurrentCount = $resource('/api/getCount', {}, {
'get': { method: 'GET', isArray: true }
});
With the above code, say for example the result returned is 5. "15" will be alerted. However, in the view, {{remaining}} is still 20. No errors, the view just doesn't update.
I have tried the following:
$timeout - nothing different happens
Making $scope.remaining an object with property "value". (I read in another post about issues with data binding of primitives vs references). No difference.
$promise and .then() - no difference
$apply results in a digest error
Note, I am also coding with Ionic, not sure if it makes a difference. I disabled caching in the Ionic config, and another service method that returns an array propagates an ng-repeat as expected.
Thanks!
I'm not sure what things look like inside that get() function, but it doesn't look right.
Assuming get() returns a promise, you should write it like this:
AcctService.getCurrentCount.get().then(calculateRemaining); //This is a $resource method
First of all you do not need to create get method to return array. Use default 'query' method of $resource. And first parameter for the method is an object of parameters. second one is success function. So change you service to this
service.getCurrentCount = $resource('/api/getCount');
And later use it as
AcctService.getCurrentCount.query({},calculateRemaining);
Also check if you are not using one way data binding {{::remaining}}
And also you have to make sure you are using right $scope, to check that make "remaining" a field of an object. You can do it this way:
$scope.myData = {};
$scope.myData.remaining = 20;
and later at the controller initialize it the same and at the html
{{myData.remaining}}
also you can use $scope.apply(); but actually that is used at different case

using data from a callback from Ebay api in Angularjs

I am trying to use the ebay api in an angular.js app.
The way the api works by itself is to pass data to a callback function and within that function create a template for display.
The problem that I am having is in adding the data returned from the callback to the $scope. I was not able to post a working example as I didnt want to expose my api key, I am hoping that the code posted in the fiddle will be enough to identify the issue.
eBayApp.controller('FindItemCtrl', function ($scope) {
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
}
console.log($scope.items); //this is undefined
})
http://jsfiddle.net/L7fnozuo/
The reason the second instance of $scope.items is undefined, is because it is run before the callback function happens.
The chances are that $scope.items isn't updating in the view either, because Angular doesn't know that it needs to trigger a scope digest.
When you use the Angular provided async APIs ($http, $timeout etc) they have all been written in such a way that they will let Angular know when it needs to update it's views.
In this case, you have a couple of options:
Use the inbuilt $http.jsonp method.
Trigger the digest manually.
Option number 1 is the more sensible approach, but is not always possible if the request is made from someone else's library.
Here's an update to the fiddle which uses $http.jsonp. It should work (but at the moment it's resulting in an error message about your API key).
The key change here is that the request is being made from within Angular using an Angular API rather than from a script tag which Angular knows nothing about.
$http.jsonp(URL)
.success($scope.success)
.error($scope.error);
Option 2 requires you to add the following line to your JSONP callback function:
globalFunc = function(root){
$scope.items = root.findItemsByKeywordsResponse[0].searchResult[0].item || [];
console.log($scope.items); //this shows the data
$scope.$apply(); // <--
}
This method tells Angular that it needs to update it's views because data might have changed. There's a decent Sitepoint article on understanding this mechanism, if you are interested.

make multiple http calls synchronously in AngularJs

I am using AngularJs in my project. I have to make multiple http calls and then return the consolidated result to my view. How to achieve this using AngularJs?
Please let me know since I am not an expert in AngularJs and need a proper approach to solve this.
Use the promise API:
var wheatherPromise = $http.get(...);
var timePromise = $http.get(...);
var combinedPromise = $q.all({
wheather: wheatherPromise,
time: timePromise
})
combinedPromise.then(function(responses) {
console.log('the wheather is ', responses.wheather.data);
console.log('the time is ', responses.time.data);
});
See the documentation for more details
make ur $http request in a seperated function or (AJS service is
recommended).
call that function in a for loop based on ur list
declare a scope variable holds an empty array inside the function
push response objects in the array
avoid defining $http.get inside a for loop which cause unexpected behavior

Resources