cannot access $scope variable out side a function - arrays

I have a variable defined in a controller:
app.controller('myController',['$scope','ajaxCall',function($scope,ajaxCall){
$scope.interviewer = {};
ajaxCall.get(/* A url */).then(function(response){
$scope.interviewer = response.data;
console.log($scope.interviewer);
});
console.log($scope.interviewer);
ajaxCall is a custom service which is used to make ajax calls. Inner console is working fine(i.e. it is showing the complete data) but the outer console is printing an empty object.Why?

Because the first A in AJAX means "Asynchronous".
The function passed to then() is executed asynchronously, a long time after the last console.log() line. It's executed once the response to the asynchronous HTTP request comes back from the server.
If it was synchronous, we wouldn't bother with promises and callback functions. We would just do
var response = ajaxCall.get(url);
But that isn't possible, so we do
ajaxCall.get(/* A url */).then(function(response){
which means: please send this request, and when the response is available, then call this function. I'll do plenty of other things in the meantime.

Related

Sending a promise from one controller to another in Angular

In my web app, I would like to load all of the user data at the beginning, in the run method and pass the data to the other controllers to be shown to the user in the dashboard.
So lets say I have a data structure on the server
data = {
x : 30,
y: 20
}
I would like to get it in one http requests (instead of creating multiple http requests and creating multiple promises)
The http request I run in the run method of the app
service.getDataFromServer = function(){
return $http.get('/admin/data').then(function(response) {
data = response.data;
});
};
This will create a promise.
I would like to take this promise and pass it to other controllers to be used.
My first question is how can I do it so the data from the promise will bind to the data I am about to show to the user.
The second question is, can I use the structure fields before the promise is even resolved?
for example
$scope.x = data.x
And by data I mean the data which is about to be resolved
Thanks
I would like to get it in one http requests (instead of creating multiple http requests and creating multiple promises)
After getting response from http call,save the data in factory/services so,you can use is at another location like controller in your case by injecting it which is most recommended.
I would like to take this promise and pass it to other controllers to be used.
how can I do it so the data from the promise will bind to the data I am about to show to the user.
make http call and save the promise.
service.getDataFromServer = function() {
var promise = $http.get('test.json');
service.savePromise(promise);
}
and
get saved promise.
.controller('testCtrl', function(service) {
service.getSavedPromise().then(function(response){
console.log(response.data)
})
})
Plunker here
The second question is, can I use the structure fields before the promise is even resolved? for example
$scope.x = data.x
// data is still undefined as promise is not resolved.so,you will get TypeError
What you can do best here,you can merge data to your existing data object/array,so,Angular two way binding can do rest of the things for you.

Angular and Meteor flicker on page load

I had an issue with and angular-meteor project flickering every time a state using the campaigns subscription, would load. By flickering, I mean the data was there, then it would go away and come back a half second later.
I added this to the resolve property of the state (using ui-router):
campaigns: ($q) => {
var deferred = $q.defer();
Meteor.subscribe('campaigns', {
onReady: deferred.resolve,
onStop: deferred.reject
});
return deferred.promise;
}
The flickering stopped, but I don't really understand this code. Can someone who understand angular break this resolve/defer situation down?
Just not sure why it worked. thanks.
$q is angular's implementation of promises.
in a very itty bitty nutshell, a promise has two callbacks that resolve when data is returned; a resolve function if the call succeeds and a reject if the call fails. whatever data it gets will be passed into these functions (essentially doing deferred.resolve(data) or deferred.reject(error)) . $q.defer() allows us to assign the resolution/rejections later.
meteor's subscribe function takes a few arguments. the string name of the collection, a function that returns an array of arguments to be passed to the collection, and an object/function. the object part of the final argument expects an "onReady" and "onStop" functions, and will execute those functions and pass along any data it gets. we pass in our callbacks here.
finally, we return the promise. resolve.campaigns will be a promise, which we can get the values from using the .then(successCallback, failureCallback) call. meteor handles this behind the scenes.

Synchronous in angular controller

In the following code, the controller is not invoking the third $http.get() call and instead goes directly goes to the end.
I want to execute all $http.get() requests. In my code, the third $http.get() depends on the second $http.get() result. Additionally, the second $http.get() depends on the first $http.get() result.
Code
Does anyone have an idea why the third $http.get() is not being invoked?
with the way you structured your code, this code below will run before the third $http.get
orderDetails['orderData'] = data;
orderDetails['kitNames'] = kitNames;
orderDetails['proteins'] = proteins;
orderDetails['dietaries'] = dietaries;
orderDetails['ingredients'] = ingredients;
you would have to put it in the third $http.get and every other code that depends on it, and that should solve your challenge
Also, your code can be refactored, so it is more readable and understandable for you to read
Suggestion:-
Actually this is a big issue with angular http call, Because http call does not support async :false
See my answer in this discussion : Angularjs $http VS jquery $.ajax
Your code look like a lot of confusions for call new http method inside of inside methods.
And your code looks like not standard format also gives lot of confusion.
So if you change any code in this file after some day's, then you need to put a microscope glass in your eye, and will see one by one lines. it's will take more times. So avoid http call only for this type of situation.
Solution:-
Avoid http call means, pleas do with Ajax call with async:false option
The code look like
$.ajax({
type: "GET",
dataType: "Json",
url: 'Your URL',
**async: false,**
success: function (returndata, status, jqxhr) {
$(this).html(returndata).hide().fadeIn();
}).fail(function() {
alert("error");
})
});
Explanation About Async:false
Setting async to false means that the statement you are calling has to complete before the next statement in your function can be called. If you set async: true then that statement will begin it's execution and the next statement will be called regardless of whether the async statement has completed yet.

AngularJS - Promise vs then?

I have 2 questions -
1) What is the difference between the "success" and "then"?
example - $http.get(url).then vs $http.get(url).success?
2) A promise means something that would be executed in the future, fine. I am not able to wrap my head on how this is difference from a function call. a promise call is executed when we make call using "$q.defer.resolve()". Isn't this a function call? so why can't this be a normal function, and executed with any other function call like foo()? Am i missing something special that a promise does!! ?
What is the difference between the "success" and "then"?
then() takes a single argument: the http response object. success() takes 4 arguments: the data of the response, the status of the response, the headers of the response, and the http config object. success() is thus easier to use when all you care about is the data returned. As said by New Dev, the returned value is different: then() returns a new promise for whatever is returned from its callback and allows you to return a new value and thus build a promise chain, whereas success() returns the original promise.
A promise means something that would be executed in the future
No, not really. A promise is the result of something you execute now, but for which the result is not immediately available. Since JavaScript is single-threaded, you can't just block and wait for the result, because that would completely freeze the application. So you just register a callback function that will be called, asynchronously, when the result is available. For example:
$http.get('/some/url')
immediately sends an HTTP request. But to get the result, we need to wait for the bytes to travel to the server, for the server to handle the request and send back a response, and for the response to travel to the browser. This could take several seconds. So what $http.get() returns immediately is a promise: i.e. an object which represents a future result (or, once the result has been received, a result that was once future).
.then returns a new promise.
.success returns the original promise. Another difference is that .success gets the response.data as an input parameter, whereas .then gets the response.
This is how it's implemented:
promise.success = function(fn) {
promise.then(function(response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
You could use .success (and .error) to handle the respective outcome of $http, but without the ability to modify the data or to reject a promise (with return $q.reject()) given to the eventual consumer of the $http promise.
Here's an illustrative example of when one may use .success vs/with .then:
return {
getData: function(p1){
return $http.get(url, {p1: p1})
.success($log.log) // can use generic functions since there is
.error($log.error) // no requirement to return data
.then(function(response){
// here can massage the data into the output format
return response.data;
});
};
I recommend always using .then since it returns a new promise without .success and .error handlers; this avoids the chance of the API consumer using the $http-specific .success/.error thus inadvertently making the assumption that $http was used under the covers.

AngularJS $http success but not working

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.

Resources