Parse-Server: Unable to query objects - javascript

at the top of my index.html, I successfully initialize Parse-Server like this:
<script>
Parse.initialize("MY_KEY");
Parse.serverURL = 'http://MY_APP_NAME.herokuapp.com/parse/';
/*var GameScore = Parse.Object.extend("Test");
var gameScore = new GameScore();
gameScore.save({playerName: "Granto"}).then(function(object) {
alert("SUCCESS BRAHSKI");
});*/
</script>
I know the initialization is successful because I'm able to save a Test Object into the server as shown in the commented code above.
However, When I try and query objects from my server, Nothing happens. What is wrong with my query?
var query = new Parse.Query("Test");
query.find({
success: function (results) {
alert("Query SUCCESS");
},
error: function (error) {
alert("Query Error:" + error);
}
});

Correct Syntax for a Parse-Server Query:
var query = new Parse.Query("Client");
query.find()
.then(function(results) {
alert("SUCCESS");
})
.catch(function(error) {
alert("ERROR");
});

Related

Parse Server Cloud Code background job query and update objects

I have a Parse Server app hosted on back4app and I am running a Background Job that runs every minute and queries the Letters class, where the column deliveryDate is less or equal to the current date, here's my main.js file:
// DELIVER A LETTER
Parse.Cloud.job("deliverLetter", function (request, status) {
var now = new Date();
// var nowTime = date.getTime();
var Letters = Parse.Object.extend("Letters");
var query = new Parse.Query(Letters);
query.lessThanOrEqualTo("deliveryDate", now);
query.find().then (function (objects) {
objects.forEach(function (obj) {
obj.set("isDelivered", true);
Parse.Cloud.useMasterKey();
obj.save(null, { useMasterKey: true } ).then(function(obj) {
response.success(obj);
}, function(error) {
response.error(error)
});
});
});
So, for instance, I save a row in the Letters class where deliveryDate is set to yesterday, in order for me to test this Cloud Code function. There's another column called isDelivered and it's set to False. So, my function above should set isDelivered into True and update my Letters's object.
But it doesn't work, so I don't know what I'm doing wrong.
Edit
Thanks to danh, I've fixed my code as it follows:
var Letters = Parse.Object.extend("Letters");
var query = new Parse.Query(Letters);
query.lessThanOrEqualTo("deliveryDate", now);
query.equalTo("isDelivered", false);
query.find().then (function (objects) {
let savePromises = objects.map(function (obj) {
obj.set("isDelivered", true);
return obj.save(null, { useMasterKey: true } );
});
Promise.all(savePromises).then(function(obj) {
response.success(obj);
}, function(error) {
response.error(error)
});
});
I would need to call another function from my main.js file which sends a push notifications and needs some parameters. I usually call it from my app, how would I call it from within that above function?
Parse.Cloud.define("pushiOS", function(request, response) {
var user = request.user;
var params = request.params;
var userObjectID = params.userObjectID
var data = params.data
var recipientUser = new Parse.User();
recipientUser.id = userObjectID;
var pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("userID", userObjectID);
Parse.Push.send({
where: pushQuery,
data: data
}, { success: function() {
console.log("#### PUSH SENT!");
}, error: function(error) {
console.log("#### PUSH ERROR: " + error.message);
}, useMasterKey: true});
response.success('success');
});
Maybe into Promise.all()?
Promise.all(savePromises).then(function(obj) {
response.success(obj);
Parse.Cloud.define("pushiOS"...
}, function(error) {
response.error(error)
});
Any save() that's in progress or not yet started when response.success() is called will be terminated (or won't get a chance to start). To fix, collect promises for all of the saves, and run them together with Promise.all(), which resolves only after all of the promises passed to it have resolved.
query.find().then (function (objects) {
// Parse.Cloud.useMasterKey(); don't need this
let savePromises = objects.map(function (obj) {
obj.set("isDelivered", true);
return obj.save(null, { useMasterKey: true } );
});
Promise.all(savePromises).then(function(obj) {
response.success(obj);
}, function(error) {
response.error(error)
});
});
Also, note, incidentally, that query.lessThanOrEqualTo("deliveryDate", now); will get all of the objects with deliveryDates before now, including the ones you processed previously. That result will get monotonically longer over time, eventually exceeding the 1 minute between runs, or blowing some other system resource.
Maybe you really want...
query.lessThanOrEqualTo("deliveryDate", now);
query.equalTo("isDelivered", false);
EDIT
The second question can be handled by factoring a promise-returning push function like this...
function pushDataToUser(userID, data)
var recipientUser = new Parse.User();
recipientUser.id = userID;
let pushQuery = new Parse.Query(Parse.Installation);
pushQuery.equalTo("userID", userID);
return Parse.Push.send({ where:pushQuery, data:data });
}
That can be called from cloud code like this...
Parse.Cloud.define("pushiOS", function(request, response) {
let params = request.params;
pushDataToUser(params.userObjectID, params.data).then(function() {
console.log("#### PUSH SENT!");
response.success('success');
}, function(error) {
console.log("#### PUSH ERROR! " + JSON.stringify(error));
response.error(error);
});
}
...and the new promise-returning function can be added to any other promise chain like this...
// function doSomething() returns a promise (like from a find() or a save()
return doSomething().then(function() {
// initialize someId and someData
return pushDataToUser(someId, someData)
});

NodeJS return SQL queries to pass to another file

I have been struggling with the returning of data for the past 2 days. I really need help in getting the data to show in another .js file but I can't seem to do so.
From all the research I have done, I know that I need the callback function in order to do the return. When I output the data in file1.js, it shows, which is correct.
However, I need to access the returned data in my file2.js but it is not showing.
Am I missing anything out? Please help, any response is greatly appreciated. Thanks.
Note that my return statement in file1.js is near the end of the code.
Also, my "res" array is ALWAYS empty when accessed outside the function. Why is this so?
file1.js
var sql = require("mssql");
// Create a configuration object for our Azure SQL connection parameters
var dbConfig = {
server: "***", // Use your SQL server name
database: "***", // Database to connect to
user: "***", // Use your username
password: "***", // Use your password
port: 1433,
// Since we're on Windows Azure, we need to set the following options
options: {
encrypt: true
}
};
var obj = {};
var res = [];
// This function connects to a SQL server, executes a SELECT statement,
// and displays the results in the console.
function getProducts(callback) {
// Create connection instance
var conn = new sql.ConnectionPool(dbConfig);
conn.connect()
// Successfull connection
.then(function () {
// Create request instance, passing in connection instance
var req = new sql.Request(conn);
// Call mssql's query method passing in params
req.query("SELECT sp.product_name, count(ss.product_id) as 'quantity' " +
"FROM smartcoolerstocks ss JOIN smartcoolerproducts sp " +
"ON sp.product_id = ss.product_id " +
"GROUP by sp.product_name ")
.then(function (recordset) {
//console.log(recordset.recordset);
conn.close();
//NEED CALLBACK FUNCTION
console.log(recordset.recordset.length);
for(var i = 0; i<recordset.recordset.length; i++ ){
res.push(recordset.recordset[i]);
}
callback(null,recordset.recordset);
process.exit(1);
})
// Handle sql statement execution errors
.catch(function (err) {
console.log(err);
conn.close();
})
})
// Handle connection errors
.catch(function (err) {
console.log(err);
conn.close();
});
}
//call Fn for db query with callback
getProducts(function(err,data){
if (err) {
// error handling code goes here
console.log("ERROR : ",err);
} else {
// code to execute on data retrieval
//console.log("result from db is : ",data.recordset);
//return data.recordset;
return res;
}
});
console.log(res); //WHY IS THIS EMPTY HERE?
module.exports = {
getProducts(){},
};
Blockquote
file2.js
var myDB2 = require('./sqltest2');
console.log(myDB2.getProducts());
Here's my output in cmd:
After the '7', there's nothing showing.
My IDEAL output should be the following if I manage to get the returned data in file2.js from file1.js:
You cannot see the res because its race condition, your console.log(res) executed earlier than recordset callback.
file1.js already executed the getProducts function so there is not data that returned to file2.js.
var sql = require("mssql");
// Create a configuration object for our Azure SQL connection parameters
var dbConfig = {
server: "***", // Use your SQL server name
database: "***", // Database to connect to
user: "***", // Use your username
password: "***", // Use your password
port: 1433,
// Since we're on Windows Azure, we need to set the following options
options: {
encrypt: true
}
};
var obj = {};
var res = [];
// This function connects to a SQL server, executes a SELECT statement,
// and displays the results in the console.
function getProducts(callback) {
// Create connection instance
var conn = new sql.ConnectionPool(dbConfig);
conn.connect()
// Successfull connection
.then(function() {
// Create request instance, passing in connection instance
var req = new sql.Request(conn);
// Call mssql's query method passing in params
req.query("SELECT sp.product_name, count(ss.product_id) as 'quantity' " +
"FROM smartcoolerstocks ss JOIN smartcoolerproducts sp " +
"ON sp.product_id = ss.product_id " +
"GROUP by sp.product_name ")
.then(function(recordset) {
conn.close();
callback(null, recordset.recordset);
process.exit(1);
})
// Handle sql statement execution errors
.catch(function(err) {
console.log(err);
conn.close();
callback(err, null);
})
}).catch(function(err) {
console.log(err);
conn.close();
callback(err, null);
});
}
module.exports = getProducts;
And file2.js
var myDB2 = require('./sqltest2');
myDB2(function(err, data){
if( err ) console.log(err);
else console.log(data);
});

ParseError: 'bad or missing username'

So I have some cloud code I am trying to write to like a post.
My database is setup that users have a likedPosts array, which has object id's of all the posts that the user liked. Users also have a column coins, that should get incremented when users like their posts.
The post object has a likes column which is an integer that gets incremented with each like, and the post object also has a posterId column, which is the object id of the user that posted it.
Here is my function right now (I am not very good at javascript and cloud code, so if there is something horribly wrong, I'm sorry)
Parse.Cloud.define("likePost", function(request, response) {
Parse.Cloud.useMasterKey();
var senderId = request.params.senderId;
var postId = request.params.postId;
var post = new Parse.Object ({objectId: postId});
var posterId = post.posterId
var poster = new Parse.User ({objectId: posterId});
var sender = new Parse.User ({objectId: senderId});
sender.add("likedPosts", postId);
poster.increment("coins");
post.increment("likes");
poster.save(null, {useMasterKey:true, success:
function(poster) {
console.log("Successfully saved poster");
}, error: function(poster, error) {
console.error("Error saving poster: " + error.message);
response.error(error);
}
});
post.save(null,{useMasterKey:true, success:
function(post) {
console.log("Successfully saved post");
}, error: function(post, error) {
console.error("Error saving post: " + error.message);
response.error(error);
}
});
sender.save(null, {useMasterKey:true, success:
function(sender) {
console.log("Successfully saved sender");
}, error: function(sender, error) {
console.error("Error saving sender: " + error.message);
response.error(error);
}
});
response.success();
});
I call the function from swift like so:
PFCloud.callFunction(inBackground: "likePost", withParameters: ["senderId" : PFUser.current()!.objectId!, " postId": postObject!.objectId!], block: { (result, error) in
if (error != nil) {
print(error!)
} else {
print("success liking")
}
})
In my logs, however, I get the following error:
2017-06-21T21:47:59.499Z - Failed running cloud function likePost for user R4d8Zrcdhw with:
Input: {"senderId":"R4d8Zrcdhw"," postId":"XXbu55PdpR"}
Error: {"code":141,"message":{"code":200,"message":"bad or missing username"}}
2017-06-21T21:47:59.492Z - bad or missing username
My guess is that the request is missing a header to define the content-type. I've seen Parse return the "bad or missing username" error via the Parse REST API if the Swift URLSession was using an incorrect content-type header.
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
or
Parse.Cloud.httpRequest({
url: 'http://www.example.com/',
headers: {
'Content-Type': 'application/json;charset=utf-8'
}
})

Issue with rendering page after performing delete function

exports.deleteItem = function (req, res)
{
var query = req.params.id;
var cart = req.session.items;
var index;
_.each(cart,function (ticket)
{
if(ticket.id === query)
{
index = cart.indexOf(ticket);
cart.splice(index,1);
}
return res.redirect(303, '/cart');
});
};
I am using this function in my routes to perform a delete operation. It works for the first few items on my list, then suddenly stops and gives me the error "Can't set headers after they are sent."
$(document).ready(function() {
$('.delete-from-cart').click(function(event)
{
$target = $(event.target);
$.ajax({
type: 'DELETE',
url: '/cart/remove/' + $target.attr('data-item-id'),
data: {
_csrf: $target.attr('data-csrf')
},
success: function(response)
{
$target.parent().parent().remove();
Materialize.toast('Ticket Removed', 4000);
window.location.href = '/cart';
},
error: function(error)
{
Materialize.toast('Error', 4000);
console.log(error);
}
});
});
});
A single request was made, which means a single response should occur.
When you execute the _.each function I'm guessing that it works if there is one item but fails when there are multiple? This is because you are trying to send multiple responses when only one is permitted.
A good explanation for this can be found here: Error: Can't set headers after they are sent to the client

Parse.com Cloud code Error: success/error was not called when trying to update a user

ive never used cloud code/javascript and I am trying to write some parse cloud code to find a user using a objectId passed in to the cloud function, and then update that users relation that holds friends and finally save that user.
below is the function im using:
Parse.Cloud.define("addFriendToFriendsRelation", function(request, response) {
Parse.Cloud.useMasterKey();
var fromUserObjectId = request.params.fromUserObjectId;
var acceptingUser = request.params.user;
var query = new Parse.Query(Parse.User);
// find the user the request was from using the objectId
query.get(fromUserObjectId, {
success: function(user) {
var fromUser = user
var relation = fromUser.relation("friends");
relation.add(acceptingUser);
fromUser.save({
success: function() {
response.success("Successfully saved the users relation")
},
error: function() {
response.error("Save failed");
}
});
},
error: function() {
response.error("Save failed");
}
});
});
I managed to piece this together using the Parse docs. but Im really not following it to well. Never used javascript and am finding the syntax confusing.
then im calling the function with
//fromUser is a PFUser object defined further up
[PFCloud callFunctionInBackground:#"addFriendToFriendsRelation" withParameters:#{#"fromUserObjectId" : fromUser.objectId} block:^(id object, NSError *error) {
}
however whenever this function is called I get a success/error was not called error. Though im calling response.success and response.error in the function so I dont know why that is? Can anyone lend a hand?
edit: after doing some more searching it looks like response.success and response.error should only be called once each, so I modified my function to look like this:
arse.Cloud.define("addFriendToFriendsRelation", function(request, response) {
Parse.Cloud.useMasterKey();
var fromUserId = request.params.fromUserObjectId;
console.log("fromUserId:");
console.log(fromUserId);
var acceptingUser = request.params.user;
console.log("acceptingUser:")
console.log(acceptingUser);
var query = new Parse.Query(Parse.User);
query.get(fromUserId, {
success: function(user) {
console.log("found user:");
console.log(user);
var fromUser = user;
var relation = fromUser.relation("friends");
relation.add(acceptingUser);
console.log("added accepting user to relation");
fromUser.save({
success: function() {
response.success("successfully saved user")
},
error: function() {
response.error("error saving user");
}
});
console.log("found a user");
},
error: function() {
console.log("error finding user");
}
});
});
An old question, but since it's been up-voted, maybe answering can help someone else :).
First off, there is an error in how you are saving fromUser.
fromUser.save({ success: ...
If you look at the api you can see that it should be of the form:
fromUser.save(null, { success: ...
But the larger problem that kept you from finding your bug is that errors are getting eaten 'cause you are using the old style method of dealing with async code instead of using promises.
Below, I have re-written to use promises. Note:
I always return promise generating calls (there are other options for catching errors in async code, but start with this.)
Put a .catch at the end. The .catch is effectively the same things as .then(null, response.error) but either way, it is imperative that there is final backstop to catch errors. In your code above, the error was in a success block, that was running async, so when there was an error, it failed with no one to hear it :).
Parse.Cloud.define("addFriendToFriendsRelation", (request, response) => {
const fromUserId = request.params.fromUserObjectId;
console.log("fromUserId:", fromUserId);
const acceptingUser = request.user;
console.log("acceptingUser:", acceptingUser)
new Parse.Query(Parse.User);
.get(fromUserId, { useMasterKey: true })
.then((fromUser) => {
console.log("found fromUser:", fromUser);
const relation = fromUser.relation("friends");
relation.add(acceptingUser);
console.log("added accepting user to relation");
return fromUser.save(null, { useMasterKey: true })
})
.then(response.success)
.catch(response.error);
});

Categories

Resources