Use Parse Query in then() when using Cloud Code - javascript

I can’t seem to get this simple Parse query to work in my cloud code then() it works outside of this but when i place the code inside of this then function nothing happens. The variables are just placeholders for now in terms of testing but i have the default TestObject class you get when you start Parse from the beginning but for some reason it just keeps on returning nothing.
Here is the full function that i am currently using.
// Function which will get the data from all the links passed into the function
Parse.Cloud.define("myNews", function (request, response) {
var promises = _.map(import_io_keys, function (news_api_key) {
return Parse.Cloud.httpRequest({
method: 'GET',
url: "https://api.import.io/store/connector/" + news_api_key + "/_query?input=webpage/url:https%3A%2F%2Fwww.designernews.co%2Fnew&&_apikey=xxxxxxxxxxxxxxxxxx",
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
}).then(function (httpResponse) {
result = JSON.parse(httpResponse.text);
var success = false;
var news_icon = "";
var news_source_name = "";
var query = new Parse.Query("TestObject");
query.find({
success: function(results) {
success = true;
news_icon = results[0].get("foo");
news_source_name = results[0].get("foo");
response.success("done" + news_icon);
},
error: function() {
success = false;
response.error("Query lookup failed");
}
});
for (var story in result.results) {
if(story.length > 0){
if (story["article_link/_text"] !== "" && story["article_link"] !== "" && story["article_time"] !== "") {
if(success){
// Do the stuff later
}
}
}
}
});
});
Parse.Promise.when(promises).then(function () {
console.log("Got all the stories");
response.success(newsJsonData);
}, function () {
response.error("No stories");
console.log("API KEY IS: " + request.params.keys);
});
});

Related

Jquery issue with $.when

I'm using a call back function which will check for 60secs. If file avaible then will return true else will return false. The call back function I'm calling after ajax call.. Here is code below :
$.ajax({
type: '..',
url: '..',
data: '..',
success: function(data) {
window.loadFile(data);
}
})
window.loadFile = function(filePath) { // I'm getting the data. Now passing to call back function
$.when(window.waitTillFileExistsAndLoad(filePath)).done(function(data) {
alert(data) // here data is giving me undefined..
});
}
var timer = 0;
window.waitTillFileExistsAndLoad = function(fileName) {
var checkFile;
return $.get(fileName, function(data) { // If file found..
timer = 0;
return true;
}).error(function() { // If file not found..
timer += 1;
if(timer == 30) {
timer = 0;
clearTimeout(checkFile);
return false;
} else {
console.log('error occured');
checkFile = setTimeout(function() {
window.waitTillFileExistsAndLoad(fileName);
}, 2000);
}
});
}
The issue is that when I'm using $.when() it's giving me undefined. Please suggest me what's wrong in my code.

How to make remote jquery validation for tied fields?

Let's say I have couple of input fields - their combination must be unique.
Each of them causes remote validation method triggering - and it's the same method for both fields. If combination is unique - it returns true.
The problem is following: when after validation error I change the field, that is not marked as erroneous, the erroneous field keeps being considered erroneous, even if method returns true (the couple is unique)!
I even don't need to make extra request to server, because the couple is unique! I just need to clear error for field, marked erroneous. However, I have not managed to do this - seems like jquery does not offer functionality for this.
Any ideas?
The relevant code is pretty huge, but the key parts are here:
this.clearErrors = function ($elements) {
var $validator = $elements.first().closest('form').validate();
$elements.each(function(index, item) {
var $parent = $(item).parent();
var element = $(item).get(0);
if ($parent.is('td')) {
$parent.removeClass(window.resources.errorCellClass);
}
$parent.find('span.' + window.resources.errorSpanClass).remove();
$validator.successList.push(element);
delete $validator.invalid[element.name];
delete $validator.submitted[element.name];
});
};
//Fixing remote method, since original one returned "pending" status all the time, as reported in other stackoverflow question
$.validator.addMethod('synchronousRemote', function (value, element, param) {
if (this.optional(element)) {
return 'dependency-mismatch';
}
var previous = this.previousValue(element);
if (!this.settings.messages[element.name]) {
this.settings.messages[element.name] = {};
}
previous.originalMessage = this.settings.messages[element.name].remote;
this.settings.messages[element.name].remote = previous.message;
if (typeof param == 'string') {
param = { url: param }
}
if (previous.old === value) {
return previous.valid;
}
previous.old = value;
var validator = this;
this.startRequest(element);
var data = {};
data[element.name] = value;
var valid = 'pending';
$.ajax($.extend(true, {
url: param,
async: false,
mode: 'abort',
port: 'validate' + element.name,
dataType: 'json',
data: data,
success: function (response) {
validator.settings.messages[element.name].remote = previous.originalMessage;
valid = response === true || response === 'true';
if (valid) {
var submitted = validator.formSubmitted;
validator.prepareElement(element);
validator.formSubmitted = submitted;
validator.successList.push(element);
delete validator.invalid[element.name];
validator.showErrors();
} else {
var errors = {};
var message = response || validator.defaultMessage(element, 'remote');
errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message;
validator.invalid[element.name] = true;
validator.showErrors(errors);
}
previous.valid = valid;
validator.stopRequest(element, valid);
}
}, param));
return valid;
});
$root.filter(':input[data-excluded-values-method]:not([readonly])').add($root.find(':input[data-excluded-values-method]:not([readonly])')).each(function () {
var $element = $(this);
$element.validate({
onkeyup: false
})
var $entityContainer = $element.closest('[data-entity]');
var $keyFields = $entityContainer.filter('INPUT[data-is-key]:not([disabled])').add($entityContainer.find('INPUT[data-is-key]:not([disabled])'));
var localizedNames = [];
$keyFields.each(function () {
localizedNames.push($(this).attr('localized-name'));
});
$element.rules('add',
{
synchronousRemote: function () {
var key = [];
var keyIsUnique = true;
$keyFields.each(function () {
key.push($(this).val());
});
return {
url: $element.attr('data-excluded-values-method'),
type: 'POST',
async: false,
data: JSON.stringify({
key: key,
entityType: $entityContainer.attr('data-entity')
}),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
dataFilter: function (isUnique) {
keyIsUnique = isUnique;
return isUnique;
},
complete: function () {
if (keyIsUnique === 'true') {
window.commonUtils.clearErrors($keyFields.filter('[name!="' + $element.attr('name') + '"]:input[data-excluded-values-method]:not([readonly])'));
}
}
}
},
messages: {
synchronousRemote: $.validator.format(window.resources.notUniqueValidationError)(localizedNames.join(' + '))
}
});
});
I've debugged jquery validate method and found what yet should be set to clear validation error:
$validator.previousValue(element).valid = true;
Now everything works.

Fire second httpRequest after parsing data from first request

I currently have a function which makes a httpRequest and parses the json received into an array of urls. I want to fire a second httpRequest after the first request is complete and data is parse, below both solutions I've tried return null.
Solution1
var promises1 = [];
Parse.Cloud.define("FetchData", function(request, response) {
var promises = _.map(urls, function(url) {
return Parse.Cloud.httpRequest({ url:url });
});
Parse.Promise.when(promises).then(function() {
createSearchUrls(arguments)
//Creates an array of urls from request data to be used in second http request
});
//Fire second HTTP request here after urls have been created from first request data
var promises1 = _.map(appTitles, function(appTitles) {
return Parse.Cloud.httpRequest({ url: appTitles});
});
Parse.Promise.when(promises1).then(function() {
//nothing returned
response.success(_.toArray(arguments));
}, function (error) {
response.error("Error: " + error.code + " " + error.message);
});
});
Solution 2 (Using then after createSearchUrl() function
Parse.Cloud.define("FetchData1", function(request, response) {
var promises = _.map(urls, function(url) {
return Parse.Cloud.httpRequest({ url:url });
});
Parse.Promise.when(promises).then(function() {
//Creates an array of urls from request data to be used in second http request
createSearchUrls(arguments).then( function() {
//Fire second HTTP request here after urls have been created from first request data
promises_1 = _.map(appTitles, function(appTitles) {
return Parse.Cloud.httpRequest({ url: appTitles});
});
})
});
Parse.Promise.when(promises_1).then(function() {
//nothing returned
response.success(_.toArray(arguments));
}, function (error) {
response.error("Error: " + error.code + " " + error.message);
});
});
createSearchUrls()
function createSearchUrls(arguments){
for (a = 0; a < arguments.length; a++){
var json = JSON.parse(arguments[a].text);
for (i = 0; i < json.feed.entry.length; i++) {
var urlEncoded = encodeURI(ENCODE JSON DATA);
var finalUrl = 'URL HERE';
appTitles.push(finalUrl);
}
}
return appTitles;
}
It looks like the idea of making a series of httpRequests and collecting the results is something that can and should be factored out....
function manyRequests(urls) {
var promises = _.map(urls, function(url) {
return Parse.Cloud.httpRequest({ url:url });
});
return Parse.Promise.when(promises).then(function() {
return _.toArray(arguments);
});
}
Now its just a matter of calling that twice....
Parse.Cloud.define("FetchData1", function(request, response) {
manyRequests(urls).then(function(results) {
createSearchUrls(results); // assigns to the gobal "appTitles"
return manyRequests(appTitles);
}).then(function(result) {
response.success(result);
}, function(error) {
response.error(error);
});
});
What that says is, call (a globally defined, presumably) list of urls and collect the results. From those results, run a local function to generate another list of urls (assigning those to a global, presumably), call those and return the result to the client.

Parse Promises Multiple httpRequest Cloud Code

I'm writing an iOs app with Parse.com and Cloud Code. Actually I want to retrieve objects which contain one picture and other informations from a website and I want to add them to a class named News. When I run my code, every object is saved (in my class, one row = one retrieved object) but unfortunately the only first one has its picture saved.... Any idea ?
I made a lot of searches about promises (series / parallels) and I think the problem comes from here..
Note : don't worry about myLink, myImgLink : I put this to make my code easy to read !
Parse.Cloud.define("rajouteNews", function(request, response) {
Parse.Cloud.httpRequest({ url: 'myUrl'}).then(function(httpResponse) {
var news = [];
var NewsClass = Parse.Object.extend("news");
for (var i = 0; i < 10 ; ++i) {
var maNews = new NewsClass();
maNews.set("link", myLink[i]); // "Other informations"
maNews.set("imgLink", myImgLink[i]);
maNews.set("title", myTitle[i]);
var promises = [];
promises.push(Parse.Cloud.httpRequest({
url: $('img').attr('src'),
method: 'GET',
}).then(function(httpResponse){
var imgFile = new Parse.File("photo.jpg", {base64:httpResponse.buffer.toString('base64')});
maNews.set("image",imgFile); // The picture
return maNews.save();
}));
news.push(maNews);
}
promises.push(Parse.Object.saveAll(news, {
success: function (list) {
response.success(news.length.toString() + " ont été sauvegardées");
},
error: function (list, err) {
response.error("Error adding news");
}
}));
return Parse.Promise.when(promises);
}).then(function(bla,result){
response.success("Job done");
}, function(error) {
response.error(error);
}
);
});
Your promises array should put out of the for loop scope. Otherwise , your promise array would be assigned to be a new blank array each loop.
Parse.File would be saved automaticly when its parent do save, you don't need to save it in advance.
So I improve your code as following, try it and tell me weather it works.
Parse.Cloud.define("rajouteNews", function(request, response) {
Parse.Cloud.httpRequest({
url: 'myUrl'
}).then(function(httpResponse) {
var promises = [];
var NewsClass = Parse.Object.extend("news");
for (var i = 0; i < 10; ++i) {
var maNews = new NewsClass();
maNews.set("link", myLink[i]); // "Other informations"
maNews.set("imgLink", myImgLink[i]);
maNews.set("title", myTitle[i]);
var maNewsPromise = Parse.Cloud.httpRequest({
url: $('img').attr('src'),
method: 'GET',
}).then(function(httpResponse) {
var imgFile = new Parse.File("photo.jpg", {
base64: httpResponse.buffer.toString('base64')
});
maNews.set("image", imgFile); // The picture
return maNews.save();
});
promises.push(maNewsPromise);
}
return Parse.Promise.when(promises)
}).then(function(bla, result) {
// this function is call when `Parse.Promise.when(promises)` is done,
//I can't figure out why you take two params.
response.success("Job done");
}, function(error) {
response.error(error);
});
});

Pass a variable to a function from another function in JavaScript (winJs)

Hi I'am working with Windows 8 app using Java Script
function fetchFromLiveProvider(currentList, globalList,value) {
feedburnerUrl = currentList.url,
feedUrl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&output=json&num=999&q=" + encodeURIComponent(feedburnerUrl);
WinJS.xhr({url: feedUrl, responseType: "rss/json"
}).done(function complete(result) {
var jsonData = JSON.parse(result.response);
//console.log(JSON.stringify(jsonData));
var entries = jsonData.responseData.feed;
});
}
function setOther(entries){
//some code here
}
I want to do is pass the entries in the fetchFromLiveProvider function to another function called setOther(entries){}. Thank you for any help...
Since WinJS.xhr returns a promise, you can do the following:
var entriesPromise = function fetchFromLiveProvider(currentList, globalList, value) {
feedburnerUrl = currentList.url,
feedUrl = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&output=json&num=999&q=" + encodeURIComponent(feedburnerUrl);
return WinJS.xhr({
url: feedUrl,
responseType: "rss/json"
});
}
function setOther(entries) {
entries.done(function complete(result) {
var jsonData = JSON.parse(result.response);
//console.log(JSON.stringify(jsonData));
var entries = jsonData.responseData.feed;
//some code here
})
}
setOther(entriesPromise);

Categories

Resources