jQuery Promises not working? - javascript

I have 2 csv's that I'm trying to read in, after which I use the data in those two to do stuff:
function getData() {
var deferredObject = $.Deferred(); //representation of some asynchronous work
d3.csv("./parse_shp.csv", function(data) {
console.log(data);
shp_array = data;
});
d3.csv("./fao_coutnry_shp.csv", function(data) {
console.log(data);
fao_array = data;
});
//once both of those are done, resolve the promise
deferredObject.resolve();
return deferredObject.promise();
}
function LevenshteinDistance() {
console.log("do stuff with the data");
}
//call LevenDistance after the promise has been resolved
getData().then(LevensteinDistance());
But that's not working... it'll print the line "do something with the data" before printing the data of the csv's.
What am I doing wrong? I used this link as an example.
I don't understand how connect deferredObject and getData()? Because even if I create the deferred object in the function, won't it just asynchronously do the csv reads anyway and then erroneously call defferedObject.resolve()?
Anyway, I'm new to promises so any help would be greatly appreciated!!

The argument to .then() must be a function. You're calling the function immediately, because you have () after the function name. It should be:
getData().then(LevenshteinDistance);

Related

angularjs $http.jsonp success data access it elsewhere

How can I access the $scope or the data obtained from success in $http outside the $http.jsonp() request?
$http.jsonp('http://example.com/?callback=JSON_CALLBACK')
.success(function(data) {
$scope.info1 = data.name;
$scope.info2 = data.company;
});
console.log("access it here outside: ",$scope.info1);
currently the console prints undefined.
Thanks for the help.
You shouldn't consider asynchronous ajax call to be work in synchronous way. You have to wait until that ajax/promise gets finished. Though don't use .success/.error they are deprecated, use .then instead to chain promise.
You must rely on the promise to promise gets resolve/reject.
Code
var promise = $http.jsonp('http://example.com/?callback=JSON_CALLBACK')
promise.then(function(response) {
var data = response.data;
$scope.info1 = data.name;
$scope.info2 = data.company;
console.log("access it here outside: ",$scope.info1);
myOtherFunction($scope.info1);
})
.catch(function(error) {
console.log(error);
});

Issue with jQuery deferred

I'm facing an issue with deferred usage where 2 nested function that should wait for each other actually run in the wrong order silently.
I cant' figure out where I mix return promise.
So here is what I try to achieve. In a mobile Cordova app, when user enter the Game view, I got a function that download question in WebSql, and I want then to retrieve one question, and then my slider function load the content.
So I nested the getQuestion function in the .done() event.
router.addRoute('game', function () {
'use strict';
//Reload Question List when User enter the Game view.
questionService.initialize().done(
//Now we got question, initialize the Game View
questionService.getQuestion().done(
function (data) {
console.log(data);
slider.slidePage(new GameView(data).render().$el);
})
);
Here is how I use the $.Deferred() in both function. First I declare my $.Deferred() and at the end of the function I return the promise.
But my getQuestion() in code below does not wait for the initialize() function to end before start.
Where did I mixed up my promise return?
var getQuestions = function(param) {
var deferred = $.Deferred();
param = param;
$.ajax({
type: 'POST',
url: 'myserver',
data: {
region: uRegion
},
success: function(value, status) {
//do something with value
this.db = window.openDatabase('database details');
this.db.transaction(function(tx) {
storeQuestion(tx);
}, function(error) {
deferred.reject('Transaction error: ' + error);
}, function() {
//Transaction success
deferred.resolve();
});
},
error: function(textStatus, exception) {}
});
return deferred.promise();
};
You are not passing the success callback handler. As per current implementation your are invoking getQuestion() immediately.
Use anonymous function, rest its fine
//Reload Question List when User enter the Game view.
questionService.initialize().done(function(){
//Now we got question, initialize the Game View
questionService.getQuestion().done(
function (data) {
console.log(data);
slider.slidePage(new GameView(data).render().$el);
})
});

Can't figure out promises with mongod and nodejs

I have a function getStuff() that needs to return the results of a query against MongoDB. I'm using nodejs and the mongod module. Here's the code I've got.
var mongo = require("mongod");
var url = "mongodb://localhost:27017/my-mongo";
function getStuff() {
var db = new mongo(url, ["stuff"]);
var promise = db.stuff.find()
.then(function (result) {
console.log(result);
return result;
}).done(function (data) {
console.log(data);
return data;
});
console.log(promise);
return promise;
}
exports.getStuff = getStuff;
I'm obviously missing something about how promises work. I'm getting good data in the first two console.log() calls. However the getStuff() function always returns undefined. This seems like it should be a super simple use case but I'm banging my head on my desk trying to get it to work properly. Any help would be greatly appreciated.
Your last log and return statement run as your .find.then.done chain are still being executed (that's Async for ya!). That's why promise is still undefined.
Try returning the entire promise, like instead of
var promise = db.stuff.find()...
try
return db.stuff.find()...
...that needs to return the results...
to get the data from getStuff
function getStuff(callback) {
var db = new mongo(url, ["stuff"]);
db.stuff.find()
.done(function (result) {
console.log(result);
callback(result);
}));
}
then you can call it like this
getStuff(function(data){
//here you will get your results
});

Promises.all does not hit catch() block when one promise fails?

I'm trying to run a function when two compilation steps are complete, but the success callback keeps getting called even one fails. Here's the code:
function compile(tplStr) {
return new Promise(function(resolve,reject) {
// compile template here
var tpl = new function(){};
resolve(tpl);
});
}
function parse(json) {
return new Promise(function(resolve,reject) {
try {
var obj = JSON.parse(json);
resolve(obj);
} catch(err) {
console.log('JSON parse failed');
reject(err);
}
});
}
var i = 0;
function bothReady() {
$('#c').text(++i);
}
function oneFailed(err) {
console.log('oneFailed hit');
$('#c').text(err.message);
}
var compileProm = compile($('#a').val());
var parseProm = parse($('#b').val());
Promise.all([compileProm,parseProm]).then(bothReady).catch(oneFailed);
$('#a').on('input', function() {
Promise.all([compile($('#a').val()),parseProm]).then(bothReady).catch(oneFailed);
});
$('#b').on('input', function() {
Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed);
});
code pen
When I create a syntax error in the JSON portion it logs "JSON parse failed" but does not log "oneFailed hit" like I'd expect. Why not? Shouldn't the .catch block be ran if any of the promises are rejected?
Your code doesn't work correctly when something is typed inside of #b because instead of passing an iterable to Promise.All 2 parameters are passed instead.
The result is that while both promises run, only the result of the first one is taken into account by the continuation of all.
The code read
Promise.all(compileProm,parse($('#b').val())).then(bothReady).catch(oneFailed);
Instead of
Promise.all([compileProm,parse($('#b').val())]).then(bothReady).catch(oneFailed);
PS: The 2 other calls are correct it explain why the problem seem to happen only when editing the JSON.

How to convert callback sample to deferred object?

I have a function that accepts a callback function where I pass the data back in. Can this converted to a deferred object for better practice?
Here is what I got:
var chapters;
var getChapters = function (fnLoad) {
//CACHE DATA IF APPLICABLE
if (!chapters) {
//CALL JSON DATA VIA AJAX
$.getJSON('/chapters.txt')
.done(function (json) {
//STORE DATA IN LOCAL STORAGE
chapters = Lawnchair(function () {
this.save(json, function (data) {
//CALL CALLBACK ON DATA
fnLoad(data);
});
});
});
} else {
//RETURN ALREADY CREATED LOCAL STORAGE
chapters.all(function (data) {
//CALL CALLBACK ON DATA
fnLoad(data);
});
}
};
Then I simply use it like this:
this.getChapters(function (data) {
console.log(data);
});
How can I use it like a promise though while maintaining the cache approach?
this.getChapters().done(function (data) {
console.log(data);
});
var chapters;
var getChapters = function (fnLoad) {
var d = new $.Deferred();
//CACHE DATA IF APPLICABLE
if (!chapters) {
//CALL JSON DATA VIA AJAX
$.getJSON('/chapters.txt')
.done(function (json) {
//STORE DATA IN LOCAL STORAGE
chapters = Lawnchair(function () {
this.save(json, function (data) {
//CALL CALLBACK ON DATA
d.resolve(data);
});
});
})
.fail(function() { d.reject(); });
} else {
//RETURN ALREADY CREATED LOCAL STORAGE
chapters.all(function (data) {
//CALL CALLBACK ON DATA
d.resolve(data);
});
}
return d.promise();
};
Relevant example
I see you have already accepted an answer, however if you take a large mental leap and store a promise of chapters instead of the chapters themselves, then the code will simplify significantly.
These days, this is probably the more generally adopted approach for a "fetch/cache" situation.
var chapters_promise;
var getChapters = function () {
//Cache data if applicable and return promise of data
if (!chapters_promise)
chapters_promise = $.getJSON('/chapters.txt').then(Lawnchair).then(this.save);
return chapters_promise;
};
What is actually promised (the chapters) will be determined by the value(s) returned by the functions Lawnchair and this.save, so you still have some work to do.
getChapters() will always return a promise, regardless of whether the data needs to be fetched or is already cached. Therefore, getChapters() can only be used with promise methods .then(), .done(), .fail() or .always(), for example :
getChapters().then(fnLoad);
You have no other way to access the chapters but that is reasonable since at any call of getChapters(), you don't know whether it will follow the $.getJSON() branch or the simple return branch, both of which return an identical promise.

Categories

Resources