I'm uploading a picture to parse.com using the following two ways. The first one using promises works, but the other doesn't. Am I missing something very basic?
Method 1:
var parseFile = new Parse.File(name, file);
parseFile.save().then(function (){
console.log('Picture has been successfully saved.');
callback(pictype, parseFile);
}, function (error){
console.log('Picture cannot be saved.', error.toString());
});
Method 2:
var parseFile = new Parse.File(name, file);
parseFile.save(null, {
success: function () {
console.log('Picture has been successfully saved.');
callback(pictype, parseFile);
},
error: function (error) {
console.log('Picture cannot be saved.', error.toString());
}
});
It depends on how the save method on Parse.File is implemented. It clearly returns a promise since that code works...it probably does not support the success and error syntax. Your code will not fail on it however it just doesn't work.
Edit: looking at the documentation you need to specify the options object (containing the success and error methods) as first argument. That is where you now specify null.
Related
I cannot get cloud code to query a user when using a "standard" function...
If I define the function (as below), it works fine...
Parse.Cloud.define("findUser1", function(request, response){
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", "2FSYI1hoJ8"); // "2FSYI1hoJ8" is the objectId of the User I am looking for
query.first({
success: function(user){
response.success(user);
},
error: function(error) {
console.error(error);
response.error("An error occured while lookup the users objectid");
}
});
});
In this version, the function will be called, but the query within will not...
function findThisUser(theObject){
console.log("findThisUser has fired... " + theObject); //confirms "theObject" has been passed in
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("objectId", "2FSYI1hoJ8"); // "2FSYI1hoJ8" is the value of "theObject", just hard coded for testing
query.first({
success: function(users){
console.log("the user is... " + users);
// do needed functionality here
},
error: function(error) {
console.error(error);
}
});
};
Cloud code does not allow global variables, and I do not see how to pass in a variable to a "defined" function from another one. This is crucial as an outside function must be called to run the required tasks on the returned user. (This happens elsewhere and has to happen AFTER everything else does. This is the confirmation, and is supposed to be used by other functions as well) All potential information found to date has not helped, and the only experience I have in server side javascript is what I have cobbled together from other cloud code...
Any ideas on what I am missing?
This link may help, i had similar issue yesterday and after moving the code a little, and having the response.success(user); in my function all worked fine.
Parse Cloud Code retrieving a user with objectId
Not your exact issue - but this may help.
Heres is the code i use now:
Parse.Cloud.define("getUserById", function (request, response) {
//Example where an objectId is passed to a cloud function.
var id = request.params.objectId;
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.equalTo("ObjectId", id);
query.first(
{
success: function(res) {
response.success(res);
},
error: function(err) {
response.error(err);
}
});
});
I'm trying to load an image using Parse.Cloud.httpRequest promise inside of one beforeSave trigger, but apparently this promisse is not called. The error callback is called, but the error message is always empty.
Is possible do it into a beforesave trigger? Or maybe it's happening because of that i'm doing this inside of foreach?
The message "pablo# after load imageUrl" don't appears in Parses log, and the message "error when save user picture>>>" appears, but the error.text is empty
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
Parse.Cloud.useMasterKey();
response.success();
var found = false;
console.log(request.object.dirtyKeys());
for (dirtyKey in request.object.dirtyKeys()) {
if (request.object.dirtyKeys()[dirtyKey] === "imageurl") {
found = true;
Parse.Cloud.httpRequest({
url: request.object.get("imageurl")
}).then(function(response) {
console.log("pablo# after load imageUrl");
var image = new Image();
return image.setData(response.buffer);
}).then(function(image) {
return image.data();
}).then(function(buffer) {
var base64 = buffer.toString("base64");
var fileTitle = request.object.id + ".png";
console.log(fileTitle);
var file = new Parse.File(String(fileTitle), { base64: base64 });
return file.save();
}).then(function(file) {
request.object.set("profileImage", file);
console.log('success');
response.success();
}, function(error) {
console.error(error);
response.error("error when save user picture>>> " + error.text);
});
}
}
if(!found){
response.success();
}
});
This is all doable with just a few improvements to the code: (1) don't call success() straight away or nothing at all will happen, (2) no need to loop dirty keys, since we're just checking for existence of one of them, (3) your code assumes that image.setData() returns a promise fulfilled by the image data: the docs are unclear about this but imply otherwise, (4) finally, let's factor the image stuff into a single, promise returning function so its easier to see what's happening...
Parse.Cloud.beforeSave(Parse.User, function(request, response) {
fetchAndSaveUserImage(request.object).then(function() {
response.success();
}, function(error) {
response.error(error);
});
}
function fetchAndSaveUserImage(user) {
if (user.dirtyKeys().indexOf("imageurl") == -1) { return false; }
var image = new Image(); // more like docs, so we have the image in any block below
var params = { url: request.object.get("imageurl") };
return Parse.Cloud.httpRequest(params).then(function(response) {
console.log("pablo# after load imageUrl");
return image.setData(response.buffer);
}).then(function() {
return image.data(); // this is likely the same as response.buffer, but the docs do it, so just to be certain...
}).then(function(buffer) {
var base64 = buffer.toString("base64");
var fileTitle = user.id + ".png";
console.log(fileTitle);
var file = new Parse.File(String(fileTitle), { base64: base64 });
return file.save();
}).then(function(file) {
request.object.set("profileImage", file);
return true;
});
}
Incidentally, I omitted useMasterKey since I saw nothing in the code needing more permission than what's already assumed in beforeSave of a User.
I am using the npm xmlreader to parse my xml I am receiving from yahoo weather on parse's cloud. I have been using the examples from the git repository and the example here: https://www.npmjs.org/package/xmlreader to try to see if I can get the contents of any node at this point and I am having no luck. I am doing it as such:
Parse.Cloud.job("getPage", function(request, status) {
var response = "I never get set";
Parse.Cloud.httpRequest({
url: 'http://weather.yahooapis.com/forecastrss?w=2442047&u=f',
success: function (httpResponse) {
console.log("Got here yo");
response = httpResponse.text;
response = response.toString();
response = parseXML(response);
status.success(response.toString());
},
error: function (httpResponse) {
status.error('Request failed with response code ' + httpResponse.status);
}
});
});
function parseXML (p1)
{
var xmlreader = require('cloud/xmlreader.js');
xmlreader.read(p1, function (err, xmldata) {
if(err) return console.log(err);
console.log( xmldata.title.text() );
});
return "hello";
}
every time I run the job I get the error.
Failed with: TypeError: Cannot call method 'text' of undefined
<title>Yahoo! Weather - Los Angeles, CA</title>
<description>Yahoo! Weather for Los Angeles, CA</description>
<language>en-us</language>
<lastBuildDate>Thu, 10 Jul 2014 10:47 am PDT</lastBuildDate>
<ttl>60</ttl>
I have imported everything correctly and installed it correctly. If I just call xmlreader.text() it won't fail but there will be nothing to print is it not reading the xml properly? Any help would be great thanks!
I was not navigating the nodes correctly. I was missing a node when trying to access the title I was just trying to do res.title instead I needed to do res.rss.title.
I am using Parse (http://parse.com) inside a Meteor Application (http://meteor.com)
I am trying to query my Parse Database from the server side, and everything is fine until I get to the query.
I get the following error:
[TypeError: Cannot call method 'getItem' of undefined]
This is what my code looks like: [I have even tried query.find()]
var VITxUser = Parse.Object.extend("VITxMaster");
var query = new Parse.Query(VITxUser);
query.equalTo("fbid", "1231212");
//no errors till here
query.first({
success: function(object) {
if (!object){
//insert the user
var GameScore = Parse.Object.extend("VITxMaster");
var gameScore = new GameScore();
gameScore.set("fbid", profile.id);
gameScore.set("registrationNumber", "12DEV0000");
gameScore.set("VITevents", "true");
gameScore.save(null, {
success: function(gameScore) {
// Execute any logic that should take place after the object is saved.
alert('New object created with objectId: ' + gameScore.id + 'and fbid: ' + profile.id);
},
error: function(gameScore, error) {
// Execute any logic that should take place if the save fails.
// error is a Parse.Error with an error code and description.
alert('Failed to create new object, with error code: ' + error.description);
}
});
}
else{
console.log("found object");
console.log(object.get("registrationNumber"));
}
}
});
I can't see a reference to getItem in your code. I suspect however that the issue is due to meteor's variable scoping. Basically in Meteor each file is variable scoped. So you if you had two files file1.js and file2.js they would be wrapped around in a function(){..}.
You would need to remove the variable scoping by not using var to define your variables. Particularly the one's you want to be accessible globally (in other files)
This is my front-end code (using fetch)
var MyModel = Backbone.Model.extend();
var MyCollection = Backbone.Collection.extend({
url: '/questions',
model: MyModel
});
var coll = new MyCollection();
coll.fetch({
error: function (collection, response) {
console.log('error', response);
},
success: function (collection, response) {
console.log('success', response);
}
});
and this is my back-end code (using app.get)
app.get('/questions', function (request, response) {
console.log('Inside /questions');
response.writeHead(200, {
'Content-Type': 'text/json'
});
response.write('{test:1}');
response.end();
});
The problem is that although the response is as expected, the client-side error callback is called. When I remove the line response.write('{test:1}');, the success callback is called. Any ideas as to what I might be doing wrong?
Well {test:1} is not valid JSON.
{ "test":"1" }
OR
{ "test":1 }
is however, try one of those instead.
Keys are strings in JSON, and strings in JSON must be wrapped in double quotes check out JSON.org for more information.
To ensure you have valid JSON for more complex objects just use JSON.stringify():
var obj = { test : 1 };
response.write(JSON.stringify(obj)); //returns "{"test":1}"
Also, the correct Content-Type for json is application/json
{test:1} isn't valid JSON, you should try { "test":"1" }.
Another solution is to check Express's render.json function to see how it does sending json to the browser:
https://github.com/visionmedia/express/blob/master/lib/response.js#L152-172
If you're using express you need to res.send will automatically convert objects into JSON. If you're worried about it, there's a new one called res.json that will convert anything into JSON.
var obj = {super: "man"}
res.send(obj) // converts to json
res.json(obj) // also converts to json
You don't need need writeHead(), write(), or end().
http://expressjs.com/guide.html