AngularJS $.post code runs after rest code - angularjs

I have created following function in AngularJS
var enq_dt = new Date();
$.post("/api/EMSAPI/EnquiryDetails?enq_no="+o_enq_no, null, function (returnedData) {
enq_dt = returnedData["D_O_O"];
console.log("Loading Post Block");
console.log(enq_dt);
});
console.log("Loading General Block ");
console.log(enq_dt);
$scope.CurrentQuotation = {
EnquiryNo:o_enq_no,
EnquiryDate: enq_dt,
QuotationBy:"TEST"
};
I am getting following result in console window.
Loading General Block
2010-11-26T00:00:00
Loading Post Block
2010-12-12T00:00:00
I want to Load Post block first and after that I want to run General Block.
What I am missing (I am new to Angular) ?
Thanks in advance.

I suggest you Google the word "asynchronous". In JavaScript, things like HTTP requests are almost always asynchronous.
To get your general code to run after the post, call it with .then():
function generalCode() {
console.log("Loading General Block ");
console.log(enq_dt);
$scope.CurrentQuotation = {
EnquiryNo:o_enq_no,
EnquiryDate: enq_dt,
QuotationBy:"TEST"
};
}
var enq_dt = new Date();
$.post("/api/EMSAPI/EnquiryDetails?enq_no="+o_enq_no, null)
.then(function (returnedData) {
enq_dt = returnedData["D_O_O"];
console.log("Loading Post Block");
console.log(enq_dt);
})
.then(generalCode);

Related

In pusher.js file, xhr.onreadystatechange is getting called multiple times

I am using pusher to add realtime updates feature to my react app. When a user updates a list item, The other user who is viewing it will see the updates in realtime. Recently I am facing some performance issues. Where page becomes unresponsive or laggy. After I did some debugging, I found this in the chrome console.
[Violation] 'readystatechange' handler took <N>ms
Then when I further dug into the issue. I see this function xhr.onreadystatechange = xhr.onprogress from pusher.js is getting called multiple times. Here is the whole piece of code where this function us residing
var http_xhr_request_hooks = {
getRequest: function (socket) {
var Constructor = runtime.getXHRAPI();
var xhr = new Constructor();
xhr.onreadystatechange = xhr.onprogress = function () {
switch (xhr.readyState) {
case 3:
if (xhr.responseText && xhr.responseText.length > 0) {
socket.onChunk(xhr.status, xhr.responseText);
}
break;
case 4:
if (xhr.responseText && xhr.responseText.length > 0) {
socket.onChunk(xhr.status, xhr.responseText);
}
socket.emit('finished', xhr.status);
socket.close();
break;
}
};
return xhr;
},
abortRequest: function (xhr) {
xhr.onreadystatechange = null;
xhr.abort();
}
};
I am not able to figure out why xhr.onreadystatechange = xhr.onprogress is getting called multiple times. Can someone please help me with this?

Can't read folder from firebase storage bucket

I'm new to both react and firebase. I'm trying to get a string of file names (just as a continuous string for right now) from a particular folder in the firebase storage bucket. My code is as follows:
getFilesList(){
var toReturn="";
toReturn+="Testing";
var storage = firebase.app().storage(".....");
var storageRef = storage.ref();
var listRef = storageRef.child("/slides/1HdDPbTarLBxzllDlA3H/Lecture1/");
listRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
toReturn+=this.getImageString(imageRef);
});
}).catch(function(error) {
toReturn+="error1";
});
return toReturn;
}
getImageString(imageRef) {
var toReturn="T1";
imageRef.getDownloadURL().then(function(url) {
var toReturn=url.toString();
}).catch(function(error) {
toReturn+="error2";
});
return toReturn;
}
I'm not getting any errors, but the return string is blank (aside from the 'Testing' prefix). The folder has about 20 jpg files, but it seems as though it isn't seeing that they are there. I did some research online about it, but I'm still not sure why my code isn't working. Please help me to know why this isn't working?
Thank you,
Jared
This isn't a problem with your framework, it's a problem with asynchronous code.
See, toReturn will eventually update with the results of that function call. The problem is that the caller of this function receives the array immediately, before any of the code in .then has a chance to touch it.
Even if the promise resolves instantly, the code above it will have already executed. Promises get put on a queue where the top item only executes after the current synchronous code has finished.
What getFilesList needs to do is return a Promise that the caller can then attach to in order to specify its own behaviour:
getFilesList(){
var toReturn="";
toReturn+="Testing";
var storage = firebase.app().storage(".....");
var storageRef = storage.ref();
var listRef = storageRef.child("/slides/1HdDPbTarLBxzllDlA3H/Lecture1/");
listRef.listAll().then(function(result) {
result.items.forEach(function(imageRef) {
toReturn+=this.getImageString(imageRef);
});
return toReturn;
}).catch(function(error) {
toReturn+="error1";
return toReturn;
});
And in the caller:
getFilesList.then(filesList => console.log(filesList))

How does Meteor methods return results?

I am using meteor/react for learning facebook graph api.
I want to access users' post on facebook timeline and display them on screen. How can that be done?
With the guidance of the solution provided here [How to perform common FB actions using Meteor?. I have tried the following code: server.js
Meteor.methods({
'seePost' : function(){
var graph=Npm.require('fbgraph');
if(Meteor.user().services.facebook.accessToken){
graph.setAccessToken(Meteor.user().services.facebook.accessToken);
var future = new Future();
var onComplete = future.resolver();
graph.get('/me/feed',function(err,result) {
console.log(result);
return onComplete(err,result);
})
Future.wait(future);
}
else{
return false;
}
}
});
client side code :
Meteor.call("seePost", function(err,result) {
if(err) console.log("error" , err);
else console.log("RES", result);
});
I expect the result displayed in the client side console since I want to show the users the posts on his/er timeline, But I get following output :
RES, undefined
You can do it using await and Meteor.callAsync
Basically the client code waits for the call to complete, and gives you the returned data
const result = await Meteor.callAsync("seePost");
Errors should be handled with a try..catch block
If you use fibers/future, you need to return something with "future".
const future = new Future();
// some code getting result or something
future.return(something);
return future.wait();
this will return something in the callback from client call.
try this code, when you're using fibers you need to "wait" for the response
Meteor.methods({
'seePost': function () {
var graph = Npm.require('fbgraph');
if (Meteor.user().services.facebook.accessToken) {
graph.setAccessToken(Meteor.user().services.facebook.accessToken);
var future = new Future();
var onComplete = future.resolver();
graph.get('/me/feed', function (err, result) {
console.log(result);
if (err) {
return future.return(false);
} else {
return future.return(result);
}
})
return future.wait();
}
return false;
}
});

How to roll back changes when there is an error in a promise chain

In my angular app I want to make changes to several locations in my firebase with a mix of transactions and set. I have written a promise chain with a little help. Now I need to handle any errors that may occur.
In the event of an error on any of the promises I would want to roll back any changes made in firebase (the successful promises) and alert the user to the failure.
Current code below
$scope.addNewPost = function() {
var refPosts = new Firebase(FBURL).child('/posts').push();
// Get tags into array for incrementing counters
var tags = $scope.post.tags.split(', ');
var allPromises = [];
// Iterate through tags and set promises for transactions to increment tag count
angular.forEach(tags, function(value, index){
var dfd = $q.defer();
var refTag = new Firebase(FBURL).child('/tags/' + value);
refTag.transaction( function (current_value) {
return current_value + 1;
}, function(error, committed, snapshot) {
if (committed) {
dfd.resolve( snapshot );
} else {
dfd.reject( error );
}
});
allPromises.push( dfd.promise );
});
// Add promise for setting the post data
var dfd = $q.defer();
refPosts.set( $scope.post, function (error) {
if (error) {
dfd.reject(error);
} else {
dfd.resolve('post recorded');
}
});
allPromises.push( dfd.promise );
$q.all( allPromises ).then(
function () {
$scope.reset(); // or redirect to post
},
function (error) {
// error handling goes here how would I
// roll back any data written to firebase
alert('Error: something went wrong your post has not been created.');
}
);
};
So what I need to know is how do I roll back any changes that happen to my firebase data in the event that one of these promises fail. There could be any number of updates happening in firebase. (for example: 3 tags being incremented via transaction and the post data being set)
How would I write the failure function to calculate what was successful and undo it? If this is this even possible.
--------------- sub question from original post has been solved ---------------
Also how do you force errors? I've tried setting a variable like below but it doesn't seem to work, is there something wrong with my .then?
refPosts.set( $scope.post, function (error) {
var forceError = true;
if (forceError) {
dfd.reject(forceError);
} else {
dfd.resolve('post recorded');
}
allPromises.push( dfd.promise );
});
There are two instances of this line, and they are both in the wrong place:
allPromises.push( dfd.promise );
In the first block, it should be in the last statement in the forEach callback, not in the transaction callback.
In the second block, it should be after the call to set(), not in the callback.
The way your code is written now, $q.all() is getting an empty array of promises. That could also be what's interfering with the forceError test you're attempting.

How to stop fetching collections in backbone

Disk is my collections object. I need to stop fetching collections
customPoll: function(time){
var set_time = 0;
if(time === undefined){
set_time = 4000;
}
var route = Backbone.history.fragment.split('/');
var self = this;
if(route[0] === "disks"){
setTimeout(function() {
Disks.fetch({update:true,success: function(){
self.customPoll();
}, error: function(){
self.customPoll();
}
});
}, set_time); //TODO Need to handle efficiently...
}
}
Am trying to call this fetching in every 4 second if some condition exist other wise i need to stop calling this fetching.
var route = Backbone.history.fragment.split('/');
var smart = new Smart.model({
"id" : route[1]
});
var self = this;
smart.save(null,{
success: function(model,event,response){
model = Disks.get(route[1]).toJSON();
$('#smart-confirm-dialog').modal('hide');
self.showStatusMsg(1,"<b> S.M.A.R.T. Test : </b>S.M.A.R.T Test started succesfully");
if(model.smart.progress === "100%"){
self.clearAllTimeout();
alert("please stop fetching....pleaseeee");
// Stop polling here . then fetch information from smart.fetch api.
Smart.fetch({update: true}); //this is another api i need to call this api now.
}else{
self.customPoll();
}
});
But it seems to be not working... Its keep on fetching collection.. How can i stop this Disk collection fetching.
My answer maybe is funny, I want to add comment, but I couldn't. can you add new field to your model and
customPoll: function(time){
var disks = this.model.toJSON();
if(disks.yourField){
// here your code
}
}
but before saving the model need to do delete disks.yourField;

Resources