Several attempts which I tried to add { or ) on missing input. I've asked different question as I missed commas and brackets and also indenting wrong way. I couldn't find what is the missing { or ) in this code.
Parse.Cloud.afterSave("StatusUpdate", function(request) {
if(request.object.existed()) {
return;
}
// if the user is Undefined
var toUser = request.object.get("user") ---< **** Line 8 ****
if (!toUser)
{
throw "Undefined toUser. Skipping push for Activity " + request.object.get('StatusUpdate') + " : " + request.object.id;
return;
}
// put Installation query here if needed
// send notifications based on the StatusUpdate and the passed in user from iOS ---< **** Line 16 ****
Parse.Cloud.useMasterKey() // depreciated in self hosted parse servers
// create query based on passed in values
Parse.Cloud.define("StatusUpdate", function(request, response) {
//query Installation for user
var Installationquery = Parse.Object.extend("Installation");
var query = new Parse.Query(Installationquery);
var message = request.params.message
query.equalTo("user", request.params.User);
query.find({
success: function(results) {
response.success("found user" + results)
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
Parse.Push.send({
where: query, // Set our Installation query
data: {
alert: createMessage(message),
badge: "Increment",
sound: ""
}
}, {
success: function() {
// Push was successful
console.log("sent ")
},
error: function(error) {
console.log("Error " + error)
}
});
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
});
//})
var alertMessage = function createMessage(request) {
var message = "";
if (request.object.get("StatusUpdate") === "likedby") {
if (request.user.get('postedby')) {
message = request.user.get('postedby') + ': ' + request.object.get('statusOBJID').trim();
} else {
message = "Someone liked on your status update.";
}
// Trim our message to 140 characters.
if (message.length > 140) {
message = message.substring(0, 140);
}
return message;
}
}
the problems with your code:
Line 1: Unmatched '{'.
Line 7: Missing semicolon.
Line 18: Missing semicolon.
Line 26: Missing semicolon.
Line 30: Missing semicolon.
Line 45: Missing semicolon.
Line 48: Missing semicolon.
Line 76: Missing semicolon.
Line 76: Expected ')' and instead saw ''.
Line 76: Missing semicolon.
fixed:
Parse.Cloud.afterSave("StatusUpdate", function(request) {
if(request.object.existed()) {
return;
}
});
// if the user is Undefined
var toUser = request.object.get("user");
if (!toUser)
{
throw "Undefined toUser. Skipping push for Activity " + request.object.get('StatusUpdate') + " : " + request.object.id;
return;
}
// put Installation query here if needed
// send notifications based on the StatusUpdate and the passed in user from ios
Parse.Cloud.useMasterKey(); // depreciated in self hosted parse servers
// create query based on passed in values
Parse.Cloud.define("StatusUpdate", function(request, response) {
//query Installation for user
var Installationquery = Parse.Object.extend("Installation");
var query = new Parse.Query(Installationquery);
var message = request.params.message;
query.equalTo("user", request.params.User);
query.find({
success: function(results) {
response.success("found user" + results);
// Do something with the returned Parse.Object values
for (var i = 0; i < results.length; i++) {
var object = results[i];
Parse.Push.send({
where: query, // Set our Installation query
data: {
alert: createMessage(message),
badge: "Increment",
sound: ""
}
}, {
success: function() {
// Push was successful
console.log("sent ");
},
error: function(error) {
console.log("Error " + error);
}
});
}
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
}
});
});
//})
var alertMessage = function createMessage(request) {
var message = "";
if (request.object.get("StatusUpdate") === "likedby") {
if (request.user.get('postedby')) {
message = request.user.get('postedby') + ': ' + request.object.get('statusOBJID').trim();
} else {
message = "Someone liked on your status update.";
}
// Trim our message to 140 characters.
if (message.length > 140) {
message = message.substring(0, 140);
}
return message;
}
};
Related
I am developing an office 365 word web addin, wherein I need to upload the currently opened document to my server. For which I am trying to get the file data using following code.
The method getSliceAsync() is returning only first slice of data.
On debugging it gives "Addin Error: Sorry, we had to restart because this addin wasn't responding" while getting second slice.
I am using this link for reference : [https://learn.microsoft.com/en-us/office/dev/add-ins/word/get-the-whole-document-from-an-add-in-for-word][1]
Here is my code:
Office.context.document.getFileAsync(Office.FileType.Compressed, { sliceSize: 65536 }, function (result) {
if (result.status == "succeeded") {
// If the getFileAsync call succeeded, then result.value will return a valid File Object
var myFile = result.value;
var filename1 = myFile.name;
console.log(filename1);
var sliceCount = myFile.sliceCount;
var slicesReceived = 0, isAllSlicesSuccess = true, docdataSlices = [];
// document.getElementById("result").innerText = "File size:" + myFile.size + "#Slices: " + sliceCount;
console.log(" File size:" + myFile.size + " #Slices: " + sliceCount, "");
makeProgress(20);
// Iterate over the file slices
for (var i = 0; i < sliceCount && isAllSlicesSuccess; i++) {
var diffPercent = ((i / sliceCount) * 100);
myFile.getSliceAsync(i, function (sliceResult) {
if (sliceResult.status == "succeeded") {
if (!isAllSlicesSuccess) { // Some slice has failed to get, no need to continue
console.log("Error", "One slice failed to get");
return;
console.log(sliceResult);
}
console.log('sliceResult', sliceResult);
console.log("Success", "i: " + i);
console.log("++slicesReceived ",slicesReceived );
console.log(" sliceCount",sliceCount );
console.log("++slicesReceived == sliceCount",slicesReceived == sliceCount);
// One chunk was got, store it in a temporal array
// ++slicesReceived;
// or you can do something with the chunk, such as sent it to a third party server
docdataSlices[sliceResult.value.index] = sliceResult.value.data;
if (++slicesReceived == sliceCount) {
getAllSlicesTime = Date.now();
var performance = (getAllSlicesTime - startTime) / 1000.0;
console.log("Success", "All slices has been get, Seconds: " + performance);
// All slices have been received
myFile.closeAsync(function (closeRes) {
if (closeRes.status == "succeeded") {
console.log("Close Success", "Success");
// DUClick();
}
else {
console.log("Close Error", closeRes.error.message);
}
});
onGetAllSlicesSucceeded(docdataSlices, false);
}
}
else {
isAllSlicesSuccess = false;
myFile.closeAsync(function (closeRes) {
if (closeRes.status == "succeeded") {
console.log("Close Success", "Success");
// DUClick();
}
else {
console.log("Close Error", closeRes.error.message);
}
});
console.log("Get Slice Error:", sliceResult.error.message);
}
});
}
}
else {
getFileTime = Date.now();
var performance = (getFileTime - startTime) / 1000.0;
console.log('Get File Error:', "Seconds: " + performance + " " + result.error.message);
}
});
Please suggest! Thanks in advance!
[1]: https://learn.microsoft.com/en-us/office/dev/add-ins/word/get-the-whole-document-from-an-add-in-for-word
I'm using Node to run this program, where is my error(s)? It's saying I'm missing ) after argument list. I can't find where this error is, I've tried putting the ) in various places. I'm using Node v5
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var stream = T.stream('statuses/filter', {
track: 'xoxo, oi, i\m fine,'
});
(stream.on('tweet', function(tweet) {
console.log('#' + tweet.user.screen_name + ': ' + tweet.text);
if (tweet.text.indexOf('RT') > -1) {
return;
}
var replyString;
if (tweet.user.utc_offset === null) {
replyString = ' Ok';
} else {
replyString = ' Okay';
}
})
(T.post('statuses/update', {
status: '#' + tweet.user.screen_name + replyString,
in_reply_to_status_id: tweet.id_str
}, function(err, data, response) {
if (err) {
console.log(err);
return;
}
}
tweet.botReplyId = data.id_str);
db.tweets.insert(tweet);
});
(end)
})
setInterval(stream, 60000);
The code seems to be a bit all over the place with regards to scope and it makes it a bit difficult to follow.
Try using something like the following which annotates it a bit and should help avoid issues like this (as it seems to validate without any errors) :
// Define your variables
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var stream = T.stream('statuses/filter', { track: 'xoxo, oi, i\'m fine,'});
// When a tweet occurs
(stream.on('tweet', function(tweet) {
// Log it
console.log('#' + tweet.user.screen_name + ': ' + tweet.text);
// Determine if it is a retweet and ignore
if (tweet.text.indexOf('RT') > -1) { return; }
// Set your reply
var replyString = (tweet.user.utc_offset === null) ? ' Ok' : ' Okay';
// Post your reply
T.post('statuses/update', { status: '#' + tweet.user.screen_name + replyString, in_reply_to_status_id: tweet.id_str}, function(err, data, response) {
// If an error occurs, log it
if (err) {
console.log(err);
return;
}
// Otherwise store your response and store it
tweet.botReplyId = data.id_str;
db.tweets.insert(tweet);
});
}));
// Check your stream every 10 minutes
setInterval(stream, 60000);
I'm trying to create a cloud Job that takes the users full name or username and saves it in lower case in another column. here's what I have so far:
Parse.Cloud.job('normaliseUsername',function(request, status) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query(Parse.User);
query.find({
success: function(items){
for (var i=0;i<items.length;i++) {
var user = items[i];
console.log(user);
var changed = user["nameChanged"];
if (changed === true) {
var username = user.username;
user.set("lowerCaseName",username.toLowerCase());
} else {
var realName = user["firstName"] + " " + user["lastName"];
user.set("lowerCaseName",realName.toLowerCase());
}
user.save();
}
}
});
});
This results in a new column, lowerCaseName, full of undefined.
how do I access properties of a PFUser in this instance? I have tried using user.get(''); but it says Cannot call method 'get' of undefined
Do it this way :
Parse.Cloud.job("normaliseUsername", function(request, status) {
Parse.Cloud.useMasterKey();
var count_user = 0;
var query = new Parse.Query(Parse.User);
query.descending('updatedAt');
query.Exist('nameChanged');
query.limit(1000);
return query.find().then(function(users) {
return Parse.Promise.when(users.map(function(user) {
count_user+= 1;
if (user.get("nameChanged")) {
user.set("canonical_firstname", user.get("username").toLowerCase());
} else {
var realName = user.get("firstname") + ' ' + user.get("lastname");
user.set("lowerCaseName", realName.toLowerCase());
}
return user.save();
}));
}).then(function() {
status.success("normaliseUsername with " + count_user + " user(s) updated.");
}, function(error) {
status.error("Uh oh, something went wrong.");
});
});
Your loop with for, will never works, you need to use Promise. More information here : http://blog.parse.com/learn/engineering/whats-so-great-about-javascript-promises/
The way the above script works, you will work with Promise in Parallel, not in Series : https://parse.com/docs/js/guide#promises
We are using CrossRider to develop an extension for Internet Explorer. Our extension has code that sends a message to the background, and the background sends a reply and calls a callback function. This works in my computer with Internet Explorer 11, but in my Friend Tom's computer (also with Internet Explorer 11) it doesn't work - the callback is not called in his computer. What is the problem and how do we fix it to work in any computer? Here is the relevant code:
_base.js:
alert("[ContentBase::getData] >>>>>"); // This happens in any computer.
var request = {command: 'get', webmail: thisObj.mContentType, param: param, type: type, contentType: contentType};
thisObj.sendRequest(request, function(response) {
alert("[ContentBase::getData] received data >>>>>"); // This doesn't happen in Tom's computer.
if (typeof(callback) === 'function') {
callback(response);
}
});
utils.js:
this.sendRequest = function(request, callback) {
if (typeof(callback) !== 'function') {
callback = function(response) {};
}
switch (Sys.platform) {
case 'crossrider':
var message = {request: request, message_id: Math.floor((Math.random() * 900000000000000) + 100000000000000)};
if (typeof thisObj.mCallbackMap === 'undefined') {
thisObj.mCallbackMap = {};
appAPI.message.addListener({channel: "message_from_background"}, function(message) {
if (typeof thisObj.mCallbackMap[message.message_id] === 'function') {
thisObj.mCallbackMap[message.message_id](message.response);
delete thisObj.mCallbackMap[message.message_id];
}
});
}
(function(callback_inner) {
thisObj.mCallbackMap[message.message_id] = function(response) {
if (typeof(callback_inner) === 'function') {
callback_inner(response);
}
};
})(callback);
appAPI.message.toBackground(message, {channel: "message_to_background"});
break;
}
};
background.js:
appAPI.message.addListener({channel: "message_to_background"}, function(params) {
MsgHandler.handle(params.request, undefined, function(responseParams) {
appAPI.message.toActiveTab({'message_id': params.message_id, 'response': responseParams}, {channel: "message_from_background"});
});
});
msgHandler.js:
this.handle = function(request, sender, callback_out) {
function callback(response) {
if (typeof(callback_out) === 'function') {
callback_out(response);
}
}
switch (request.command) {
case "get":
switch (request.type) {
case "all":
var data = Controller.getData();
alert("[MsgHandler::handle] get / all, data.length = " + JSON.stringify(data).length + ", data = " + JSON.stringify(data)); // This happens in any computer.
callback({data: data});
break;
}
break;
}
return true; //this return is needed for chrome in order to execute callbacks
};
Sys.platform is always equal to 'crossrider'.
Update: When JSON.stringify(data).length was 5981 bytes the message was received, but when it was 10157 bytes the message was not received by the active tab (with appAPI.message.toActiveTab). What is the limit on the size of objects sent from the background and how do we send big objects to the tabs (up to 100KB)?
Our Extension ID is 43889. I'm using Internet Explorer 11 but this extension should work on all versions of Internet Explorer.
By the way, other calls from the background work, only this specific call doesn't work. We tried several times in Tom's computer and it never works.
Edit: I created a simple extension with the same problem, Extension ID is 67708. Here is the code of the simple extension:
extension.js:
appAPI.ready(function($) {
alert("appAPI.platform = " + appAPI.platform);
if (appAPI.platform === 'IE') {
appAPI.message.addListener({channel: "message_from_background"}, function(message) {
alert("message_from_background received, message_id = " + message.message_id + ", message.length = " + JSON.stringify(message).length + ", message = " + JSON.stringify(message));
});
appAPI.message.toBackground({}, {channel: "init_background"});
}
});
background.js:
appAPI.ready(function($) {
alert("appAPI.platform = " + appAPI.platform);
if (appAPI.platform === 'IE') {
var ready = false;
appAPI.message.addListener({channel: "init_background"}, function(params) {
if (ready === false) {
alert('init_background, ready = ' + ready);
ready = true;
var message_id = 9999;
var responseParams = {'a': 1, 'b': 2, 'c': 3};
alert('sending message to active tab, message_id = ' + message_id + ', responseParams.length = ' + JSON.stringify(responseParams).length);
appAPI.message.toActiveTab({'message_id': message_id, 'response': responseParams}, {channel: "message_from_background"});
var message_id = 9998;
var responseParams = {
// a big object
};
alert('sending message to active tab, message_id = ' + message_id + ', responseParams.length = ' + JSON.stringify(responseParams).length);
appAPI.message.toActiveTab({'message_id': message_id, 'response': responseParams}, {channel: "message_from_background"});
alert(appAPI.platform);
}
});
}
});
When JSON.stringify(responseParams).length is 19 bytes, the message is received by the active tab, but when it's 10576 bytes, the message is not received.
#Uri Thanks for the updated question.
In light of the new information, I would draw your attention to the note in the docs (appAP.message) about Internet Explorer limitations:
Messages are converted to JSON strings before they are sent. Due to a
limitation in Internet Explorer, the maximum length of the JSON string
is 8000 bytes (8Kb).
You can work around the issue by saving the data in the local database and sending a short message to the active tab to trigger it to read the data. The following is a simplified example of the flow:
background.js:
appAPI.ready(function($) {
appAPI.db.async.set(
'my-data',
myData,
appAPI.time.minutesFromNow(1),
function() {
appAPI.message.toActiveTab({type: 'get-data'});
}
);
});
extension.js:
appAPI.ready(function($) {
appAPI.message.addListener(function(msg) {
if (msg.type === 'get-data') {
appAPI.db.async.get('my-data', function(data) {
// do something with data
});
}
});
});
[Disclosure: I am a Crossrider employee]
OK, since the size of objects in the messages is limited to 8000 bytes, I divided the objects to packets of size up to 5000 bytes. Here is the code of my extension:
utils.js:
this.sendRequest = function(request, callback) {
if (typeof(callback) !== 'function') {
callback = function(response) {};
}
switch (Sys.platform) {
case 'crossrider':
var message = {request: request, message_id: Math.floor((Math.random() * 900000000000000) + 100000000000000)};
if (typeof thisObj.mCallbackMap === 'undefined') {
thisObj.mCallbackMap = {};
thisObj.mResponseObject = {};
appAPI.message.addListener({channel: "message_from_background"}, function(message) {
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", checking message...");
if ((typeof(message) === 'object') && (!(message === null)) && (typeof(message['divided_object_length']) === 'number')) {
if (typeof thisObj.mResponseObject[message.message_id] === 'undefined') {
thisObj.mResponseObject[message.message_id] = {}
}
var limit = message['divided_object_length'];
var packet_id = message['packet_id'];
var packet = message['packet'];
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", limit = " + limit + ", packet_id = " + packet_id + "...");
thisObj.mResponseObject[message.message_id]['packet_' + packet_id] = packet;
var message_is_ready = true;
for (var packet_id = 0; packet_id < limit; packet_id++) {
if (typeof thisObj.mResponseObject[message.message_id]['packet_' + packet_id] === 'undefined') {
var message_is_ready = false;
}
}
if (message_is_ready) {
delete message['divided_object_length'];
delete message['packet_id'];
delete message['packet'];
var s = '';
for (var packet_id = 0; packet_id < limit; packet_id++) {
s += thisObj.mResponseObject[message.message_id]['packet_' + packet_id];
}
message.response = JSON.parse(s);
delete thisObj.mResponseObject[message.message_id];
}
} else {
var message_is_ready = true;
}
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", message_is_ready = " + message_is_ready + "...");
if (message_is_ready) {
if (typeof thisObj.mCallbackMap[message.message_id] === 'function') {
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", calling function...");
thisObj.mCallbackMap[message.message_id](message.response);
delete thisObj.mCallbackMap[message.message_id];
}
}
});
}
(function(callback_inner) {
thisObj.mCallbackMap[message.message_id] = function(response) {
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", checking inner function...");
if (typeof(callback_inner) === 'function') {
alert("[Utils::sendRequest] got response, message_id = " + message.message_id + ", calling inner function...");
callback_inner(response);
}
};
})(callback);
appAPI.message.toBackground(message, {channel: "message_to_background"});
break;
}
};
background.js:
appAPI.message.addListener({channel: "message_to_background"}, function(params) {
alert("background.js :: message received, params = " + JSON.stringify(params));
MsgHandler.handle(params.request, undefined, function(responseParams) {
alert("background.js :: message received callback, message_id = " + params.message_id + ", sending response.");
var s = JSON.stringify(responseParams);
if ((typeof(s) === "string") && (s.length > 5000)) {
var limit = Math.floor((s.length - 1) / 5000) + 1;
alert("background.js :: message received callback, message_id = " + params.message_id + ", sending response, s.length = " + s.length + ", limit = " + limit + ".");
for (var packet_id = 0; packet_id < limit; packet_id++) {
var message = {};
message['divided_object_length'] = limit;
message['message_id'] = params.message_id;
message['packet_id'] = packet_id;
message['packet'] = s.substr(packet_id * 5000, 5000);
appAPI.message.toActiveTab(message, {channel: "message_from_background"});
}
} else {
appAPI.message.toActiveTab({'message_id': params.message_id, 'response': responseParams}, {channel: "message_from_background"});
}
});
});
The rest of the code is the same like in my question (the alerts are just for debugging, we remove them in production).
I have a class with (currently) 1567 objects. They are urls,title and publication dates of article which I parse from RSS feeds of websites. The cloud job is periodic, so the objects keep on increasing. Although I check for uniqueness in beforesave, from time to time some duplicate items creep up, approximately 10% of objects are duplicate.
I have been trying to make a job to delete these duplicates and want to make a query logic which can get ALL the objects at once. The maximum limit of query is 1000. I referred to this question on Parse Help, and tried to convert it into JavaScript cloud code.
Parse.Cloud.job("DeleteDuplicate", function(request, status) {
var query = new Parse.Query(NewsArticle);
var allObjectArray= [];
var limit = 1000;
var skip = 0;
var repeat = true;
query.limit(limit);
query.skip(skip);
do{
query.find({
success: function(results) {
allObjectArray.push(results.concat());
if(results.length === limit){
skip = skip+limit;
query.skip(skip);
repeat = true;
console.log("true");
}else{
repeat = false;
console.log("false");
}
console.log("Successfully retrieved " + results.length);
},
error: function(error) {
alert("Error: " + error.code + " " + error.message);
status.error("Error: " + error.code + " " + error.message);
}
});
}while(repeat);
status.success("final length "+allObjectArray.length);
});
The code fails with the Job Status of "Could not connect to Cloud Code". I think it goes to infinite loop and times out after 2-3 minutes. If anyone can help, that would be great.
EDIT: Can using Promise help?
EDIT 2: Been trying Promise now -
Parse.Cloud.job("jobFindAll", function(request, status) {
var query = new Parse.Query(NewsArticle);
var allObjectArray= [];
var limit = 1000;
var skip = 0;
var repeat = false;
query.limit(limit);
query.skip(skip);
var promiseList = [];
console.log("in job");
query.find().then(function(results) {
console.log("results.length "+results.length);
allObjectArray = results.slice();
console.log("allObjectArray.length "+allObjectArray.length);
if(results.length === limit){
console.log("smaller");
skip = skip+limit;
do{
console.log("first repeat = "+repeat);
promiseList.push(functionFindAll(allObjectArray, limit, skip));
console.log("promiseList - "+promiseList);
repeat = promiseList[promiseList.length-1];
console.log("looping repeat = "+repeat);
}while(repeat);
return Parse.Promise.when(promiseList);
}else{
console.log("longer");
}
}).then(function(){
console.log("in then");
status.success("final length "+allObjectArray.length);
}, function(error) {
status.error("Error: " + error.code + " " + error.message);
}
);
});
function functionFindAll(allObjectArray, limit, skip){
var returnPromiseList = [];
var query_new = new Parse.Query(NewsArticle);
query_new.limit(limit);
query_new.skip(skip);
query_new.find().then(function(results) {
console.log("function results.length "+results.length);
if(results.length === limit){
skip = skip+limit;
query.skip(skip);
allObjectArray.push(results.concat());
console.log("true in function");
return Parse.Promise.as(true);
}else{
allObjectArray.push(results.concat());
return Parse.Promise.as(false);
console.log("false in function");
}
},
function(error) {
console.log("Error: " + error.code + " " + error.message);
return Parse.Promise.as("ERROR!");
}
);
console.log("below "+allObjectArray.length);
}
Now the code doesnt enter the query_new.find(). The log messages in the function doesnt appear, directly the message "below...." appears.
The following code will find all the items in the class, it does not use skip because parse.com has another freaking limit call "unable to skip more than 10000 items". it skip using the objectId.
Parse.Cloud.job("findAll", function(request, status) {
var result = [];
var processCallback = function(res) {
result = result.concat(res);
if (res.length === 1000) {
process(res[res.length-1].id);
return;
}
// do something about the result, result is all the object you needed.
status.success("final length " + result.length);
}
var process = function(skip) {
var query = new Parse.Query("NewsArticle");
if (skip) {
console.log("in if");
query.greaterThan("objectId", skip);
}
query.limit(1000);
query.ascending("objectId");
query.find().then(function querySuccess(res) {
processCallback(res);
}, function queryFailed(reason) {
status.error("query unsuccessful, length of result " + result.length + ", error:" + error.code + " " + error.message);
});
}
process(false);
});
All JS calls in Parse are asynchronous, so your function is spawning infinite threads (even if it was synchronous, your query.skip(skip) would need to go inside the while loop not before it.
Try moving the query out to its own function, which is called recursively on success until you have read all of your objects. You should be able to adapt the code in this answer, which is for a similar problem: https://stackoverflow.com/a/17268263/1176247