For my app I have a long running task that generates stats. I would like the stats to be available to my users as a json file. Is there a way using parse to store the results of the task as a json that my users can retrieve? It would be great if there was some server side caching that I could take advantage of as well.
UPDATE
The following code takes my array of dictionaries and saves it as a file. I am now trying to store the file as part of a table called Cache. However the result is
Input: {}
Result: undefined
The code snippet looks like
var Buffer = require('buffer').Buffer;
...
var json = <array of dictionaries>;
var jsonStr = JSON.stringify(json);
var buf = new Buffer(jsonStr, 'utf8');
var json64 = buf.toString('base64');
var parseFile = new Parse.File('result', { "base64" : json64 }, 'application/json');
parseFile.save().then(function(parseFile) {
// The file has been saved to Parse.
var cache = new Cache();
attr = {};
attr['file'] = parseFile;
console.log(parseFile.url());
cache.save(attr, {
success : function(result) {
status.success("Cached");
},
error : function(result, error) {
status.error("Error: + " + error.message);
}
});
}, function(error) {
console.log(error);
status.error(error.message);
});
Related
We are very new to programming and have a simple question. We are developing a very simple Google search app that searches strings on Google using client-server communication. We have a simple subset of Javascript here:
var firstName = some_string
var lastName = some_string
var googleSearch = firstName + lastName;
googleSearch = JSON.stringify(googleSearch);
We need to link this code to our NodeJS code to do the actual searching.
var google = require('google');
google.resultsPerPage = 25;
var nextCounter = 0;
google(googleSearch, function(err,res) { // Note googleSearch is from
// the frontend Javascript code
// that we want to pull the data from.
if (err console.error(err)
var link = res.links[0];
console.log(link.href);
var myLink = link.href;
})
We want to take the data from the googleSearch variable from our front-end code and utilize it in our server-side code. Then we want to display the data from myLink , which is in our server-side code, back into our front-end code.
What you need to do is make an Ajax request from your front end to your server.
If you use jquery, you can do something like this
$.ajax({
url: YOUR_SERVER_URL+"/getData",
data: {
"google_search": googleSearch,
},
method: "GET",
//use data type json if your server returns json
dataType: "json",
success: function(result) {
console.log("data fetched Successfully");
//result is the data your server returned.
console.log(result);
},
error: function() {
console.log("Something went wrong, data could not be fetched");
}
});
On your server side if you are using Express with Node,
you can return JSON by doing something like this:
var app = express();
app.get('/getData', function(req, res, next) {
var google = require('google');
google.resultsPerPage = 25;
var nextCounter = 0;
//getting query data that you passed from front end
var googleSearch = req.query.google_search;
google(googleSearch, function(err, res) {
if (err console.error(err) var link = res.links[0]; console.log(link.href);
var myLink = link.href;
})
//sending json data as response
res.json(myLink);
});
If you are using localhost, then your server url will be something like "https://localhost:5000".
My cloud code returns this error when I run it ever since migrating to Azure. It worked fine before migrating. I do recall seeing a post about needing to change some parts of cloud code (e.g. Parse.Cloud.useMasterKey();) now that Parse has gone open source, but I cannot find it anywhere.
Here's the error:
2016-04-20 10:01:37.627 App Name [Error]: {
result = Fail;
} (Code: 141, Version: 1.12.0)
2016-04-20 10:01:37.628 App Name {
NSLocalizedDescription = {
result = Fail;
};
code = 141;
error = {
result = Fail;
};
temporary = 0;
}
And here's my cloud function:
Parse.Cloud.define("addFriendRelation", function(request, response) {
Parse.Cloud.useMasterKey();
var currentUser=Parse.User.current();
var query = new Parse.Query(Parse.User);
var userId = request.params.userId;
query.get(userId,
{
success: function (object)
{
console.log(object.objectId);
var toUserFriend = object.relation("friends");
toUserFriend.add(currentUser);
object.save();
console.log("Success");
var jsonObject = {
"result" : "Success"
};
response.success(jsonObject);
},
error: function (object, error)
{
console.log("Fail");
var jsonObject={
"result" : "Fail"
};
response.error(jsonObject);
}
});
});
Thank you!
I believe the issue you are having originates from where you have
var currentUser = Parse.User.current();
This code is wrong.
You can however get the user that made the request using.
var user = request.user;
I wrote some backend code for a Parse.com mobile app a couple of years ago, and have just been asked to add a feature. However, I found that after a small tweak the code wouldn't succeed. So, I rolled back to the working copy, downloaded, then deployed that back and it wouldn't work either! I wonder if this is a change in the Parse software?
The code is failing at the save method as all the logs are fine until then. The log for the error case shows 'No message provided'. If I don't use the message attribute it just shows '{}', so I presume it's empty. I have put the promise resolution in the error case to stop the job timing out while I debug. One thing I have never understood is why I have to make two Seed objects and piggy-back off one to save correctly. If I did a.save(null,...) it wouldn't work.
Any help would be fantastic. Thanks!
PS: Apologies for the indenting below - it is correct in my file.
function flush() {
//Clear the previous records from the class.
var Seed = Parse.Object.extend("Seeds");
var _ = require("underscore");
var arr = [];
var query = new Parse.Query(Seed);
return query.find().then(function(oldSeeds) {
_.each(oldSeeds, function(oldSeed) {
arr.push(oldSeed.destroy());
});
return Parse.Promise.when(arr);
});
}
Parse.Cloud.job("fetchjson", function(request, status) {
var url = 'someurl';
flush().then(function() { Parse.Cloud.httpRequest({url: url}).then(function(httpResponse){
var Seed = Parse.Object.extend("Seeds");
var jsonobj = JSON.parse(httpResponse.text);
var _ = require("underscore");
var results = [];
// do NOT iterate arrays with `for... in loops`
_.each(jsonobj.seeds, function(s) {
var p = new Parse.Promise();
results.push(p); // Needs to be done here or when() will execute immediately with no promises.
var seed = new Seed();
var a = new Seed(s);
var image_url = a.get("image")
//Get the JSON.
Parse.Cloud.httpRequest({url: image_url}).then(function(response) {
console.log("Fetching image at URL: " + image_url);
//Create a new image object and save, passing ref through promise.
var file = new Parse.File('thumb.jpg', { base64: response.buffer.toString('base64', 0, response.buffer.length) });
return file.save();
}).then(function(thumb) {
console.log("Attaching thumb to object");
//Set image ref as object attribute.
a.set("imageFile", thumb);
console.log("Parsing views into viewsint");
//Save decimal string as int into another attribute.
a.set("viewsInt", parseInt(a.get("views")));
console.log("Parsing description into descriptionarray");
//Save string as array into another attribute.
var dar = new Array(1);
//dar[0] = a.get("description")
a.set("descriptionarray", [a.get("description")]);
}, function(error) {
console.log("Error occurred :(");
}).then(function(){
console.log("Saving object");
//Save the object and resolve the promise so we can stop.
seed.save(a,{
success: function(successData){
console.log(successData);
p.resolve(successData);
},
error: function(error){
console.log(error.message);
p.resolve(error);
}
});
});
});
// .when waits for all promises to be resolved. This is async baby!
Parse.Promise.when(results).then(function(data){
console.log("All objects saved");
status.success("Updated Succesfully");
});
}, function(error) {
//Oh noes :'(
console.error('Request failed with response code ' + httpResponse.status);
status.error("Update Failed");
});
});
});
I changed your code a bit and put some comments to explain:
// DEFINE THESE ON THE TOP. NO NEED TO REPEAT.
var _ = require("underscore");
var Seed = Parse.Object.extend("Seeds");
function flush() {
//Clear the previous records from the class.
var arr = [];
var query = new Parse.Query(Seed);
return query.find().then(function(oldSeeds) {
_.each(oldSeeds, function(oldSeed) {
arr.push(oldSeed.destroy());
});
return Parse.Promise.when(arr);
});
}
Parse.Cloud.job("fetchjson", function(request, status) {
var url = 'someurl';
flush().then(function() {
Parse.Cloud.httpRequest({url: url}).then(function(httpResponse){
var jsonobj = JSON.parse(httpResponse.text);
var results = [];
_.each(jsonobj.seeds, function(s) {
// ONE SEED OBJECT WITH INITIAL SET OF DATA FROM JSON
var seed = new Seed(s);
var image_url = seed.get("image")
// A SERIAL PROMISE FOR EACH SEED
var promise = Parse.Cloud.httpRequest({url: image_url}).then(function(response) {
console.log("Fetching image at URL: " + image_url);
//Create a new image object and save, passing ref through promise.
var file = new Parse.File('thumb.jpg', { base64: response.buffer.toString('base64', 0, response.buffer.length) });
return file.save();
}).then(function(thumb) {
// SETTING MORE PROPERTIES
//Set image ref as object attribute.
console.log("Attaching thumb to object");
seed.set("imageFile", thumb);
//Save decimal string as int into another attribute.
console.log("Parsing views into viewsint");
seed.set("viewsInt", parseInt(seed.get("views")));
//Save string as array into another attribute.
console.log("Parsing description into descriptionarray");
seed.set("descriptionarray", [seed.get("description")]);
// SAVING THE OBJECT
console.log("Saving object");
return seed.save();
});
// PUSH THIS PROMISE TO THE ARRAY TO PERFORM IN PARALLEL
results.push(promise);
});
Parse.Promise.when(results).then(function(data){
console.log("All objects saved");
status.success("Updated Succesfully");
});
}, function(error) {
console.error('Request failed with response code ' + httpResponse.status);
status.error("Update Failed");
});
});
});
Thanks knshn. I had refactored the code a lot since that version (including several of the changes you made), but I had posted the version that was identical to that which was working fine before. Your changes let me see the right error. For some reason doing the simple single object implementation didn't work for me originally, hence the nasty workaround. It works now though.
I have now found the culprit - the Seed class had an attribute called 'id'. With the old version this worked fine, but when I deployed that code now it gave an error 101: 'object not found for update'. This must be because the new Parse code is mixing that up with the internal objectId and getting confused that the id is different to what it expects. I wonder how that could still work with the rollback though. Perhaps the at version was tagged to use the older Parse code.
My fix was to use a different name for the id - 'seed_id'.
I am using the following code to get a single entry from parse.com in my corona sdk app. Is there a way to get two entries at the same time, say x1=55.317269 and x1=55.21354. I need the corresponding values for both entries rather than one.
local params = {x1=55.317269}
params.headers = headers
params.body = json.encode ( params )
network.request( "https://api.parse.com/1/functions/getFeatured","POST",getData,params)
The following is my cloud function.
Parse.Cloud.define("getFeatured", function(request, response) {
var query = new Parse.Query("testClass");
query.equalTo("x1", request.params.x1);
query.find({
success: function(results) {
var sum = 0;
sum = results[1].get("y1");
response.success(sum);
},
error: function() {
response.error("movie lookup failed");
}
});
});
Try this -
Parse.Cloud.define("getFeatured", function(request, response) {
var query = new Parse.Query("testClass");
query.containedIn("x1", ARRAY_OF_VALUES_TO_BE_MATCHED);
query.find({
success: function(results) {
// Modify/Create Proper Response Here
respones.success(results);
},
error: function() {
response.error("movie lookup failed");
}
});
});
I've been scratching my head over this for a while. What am I doing wrong? Your help is much appreciated :)
I've tried many different image codes, but I think it's a promise issue I'm seeing. With the code below I only see the "Start of loop" log message.
If I move the results push outside the promise structure to underneath then I see the Stage log messages, albeit after all the Start of loops have printed (hence why I put the push in the then function).
Parse.Cloud.job("fetchjson", function(request, status) {
var url = 'some json url';
Parse.Cloud.httpRequest({url: url}).then(function(httpResponse){
//var Image = require("parse-image");
var Seeds = Parse.Object.extend("Seeds");
var jsonobj = JSON.parse(httpResponse.text);
var results = [];
// do NOT iterate arrays with `for... in loops`
for(var i = 0; i < jsonobj.seeds.length; i++){
var seed = new Seed();
var a = new Seed(jsonobj.seeds[i]);
console.log("Start of loop");
Parse.Cloud.httpRequest({url: a.get("image") }).then(function(response) {
console.log("Stage 1");
//var file = new Parse.File('thumb.jpg', { base64: response.buffer.toString('base64', 0, response.buffer.length) });
//return file.save();
return "hi"
}).then(function(thumb) {
console.log("Stage 2");
//a.set("imageFile", thumb);
//a.set("viewsInt", parseInt(a.get("views")));
}, function(error) {
console.log("Error occurred :(");
}).then(function(){
results.push(seed.save(a)); // add to aggregate
});
}
// .when waits for all promises
Parse.Promise.when(results).then(function(data){
status.success("All saved");
});
}, function(error) {
console.error('Request failed with response code ' + httpResponse.status);
status.error("Failed");
});
});