cloud code in parse.com doesn't work to all data - javascript

I just start learning how to modify my database in Parse.com. I'm using cloud code in my mac.
In my database, I got around 150 data, with class openhour and closehour. Unfortunately, it was written in string. It's structure is like this 12:30.
I want to convert all of it from string to number, and store it in class openHour and closeHour. For an example, I will change 12:30 as string, to 12.5 as number.
I've wrote this code, deploy it, and execute it using terminal in mac. It seems succeeded since I can see some of my data in class openHour and closeHour are being filled.
My problem is, there are several data that are still empty. Can someone show me why this is happening? did I miss something?
var _ = require('underscore.js');
Parse.Cloud.define("openclose", function(request, response) {
Parse.Cloud.useMasterKey();
var query = new Parse.Query("Places");
query.limit = 1000;
query.find().then(function(results) {
_.each(results, function(result) {
var openString = result.get("openhour");
var openHourString = openString.slice(0,2);
var openHour = Number(openHourString);
var openMinuteString = openString.slice(3);
var openMinute = Number(openMinuteString);
result.set("openHour", openMinute/60 + openHour);
var closeString = result.get("closehour");
var closeHourString = closeString.slice(0,2);
var closeHour = Number(closeHourString);
var closeMinuteString = closeString.slice(3);
var closeMinute = Number(closeMinuteString);
result.set("closeHour", closeMinute/60 + closeHour);
});
return Parse.Object.saveAll(results);
}).then(function(results) {
response.success(results);
}, function(error) {
response.error(error);
});
});

Try adding a "return" before before the query.find()
return query.find().then(function(results) {
Also - I assume you have < 1,000 rows of data? Otherwise, you will need to make this recursive because of the max query limit.

Related

JavaScript random item from an imported array behaving strangely

The following code seems to be behaving strangely. Basically, I'm importing a list of line-separated sentences from a text file, then making an array out of them. But when I try to choose a random sentence from the array, it doesn't work because sentenceString becomes undefined.
However, when I run
Math.floor(Math.random() * (sentenceArr.length) + 1);
I get a nice random number as expected.
And when I run sentenceArr.length
I get the number 12, which is indeed the length.
What am I missing?
var sentenceArr = [];
$.get('sentences.txt', function(data){
sentenceArr = data.split('\n');
});
var rand = Math.floor(Math.random() * (sentenceArr.length) + 1);
var sentenceString = sentenceArr[rand];
var sentence = sentenceString.split(' ');
Update:
I tried making a Promise as suggested below, but it still doesn't seem to be working. My new code with the Promise looks like this:
var sentenceArr = [];
var done = false;
function loadSentences() {
var rand = Math.floor(Math.random() * (sentenceArr.length) + 1);
var sentenceString = sentenceArr[rand];
var sentence = sentenceString.split(' ');
};
$.get('/sentences.txt', function(data){
sentenceArr = data.split('\n');
done = true;
});
var isItDone = new Promise(function(resolve) {
if(done) {
resolve('it worked');
}
});
//consume the promise:
var checkIfDone = function() {
isItDone
.then(function (fulfilled) {
loadSentences();
})
.catch(function (error) {
console.log('oops, it failed');
});
};
checkIfDone();
This seems to always return "oops, it failed", as if the promise is never fulfilled. However, when I check the value of "done", it is "true", meaning the Ajax request was completed before moving on to the next steps. Could anyone enlighten me? I've read three tutorials on promises already, and can't seem to figure out my error in applying the concept to my own code. Thank you.
The problem is you are trying to manipulate the file content before the response of server be complete.
Take a look at promises to understand more https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
And the way to solve your question using jquery ajax api.
var sentenceArr = [];
var file = 'path/to/file';
$.get(file)
.done(function (data) {
sentenceArr = data.split('\n');
var rand = Math.floor(Math.random() * (sentenceArr.length) + 1);
var sentenceString = sentenceArr[rand];
var sentence = sentenceString.split(' ');
console.log(sentenceArr)
console.log(rand)
console.log(sentenceString)
console.log(sentence)
});
Thanks, I solved the issue by first wrapping everything in a function, and using .then() to run everything only after the Ajax "get" was completed:
var sentenceArr = [];
const getData = () =>
$.get('http://eslquiz.net/wordmix/sentences.txt', function(data){
})
.then(data => { // use this format to run function only after json get is done (since it's async)
// "data" is the contents of the text file
sentenceArr = data.split('\n');
console.log('Made sentence array');
loadSentences();
});

twitterbot is repeating itself

For a bit of fun I decided to put a twitter bot together using a youtube based tutorial, and while this was relatively easy to execute I am having an issue with the bot repeating the same tweet a few times before it tweets something new.
At this stage the bot is only set up to post tweets that are put together at random from three seperate arrays
Array.prototype.pick = function() {
return this[Math.floor(Math.random()*this.length)];
};
console.log("The bot is starting");
var Twit = require('twit');
var T = new Twit(require('./config.js'));
var partOne = require('./content/partone.js');
var partTwo = require('./content/parttwo.js');
var emoji = require('./content/emojis.js');
var statusOne = partOne.pick();
var statusEmoji = emoji.pick();
var statusTwo = partTwo.pick();
function tweetIt() {
var tweet = {
status: statusOne + statusTwo + ' ' + statusEmoji
};
T.post('statuses/update', tweet, tweeted);
function tweeted(err, data, response) {
if (err) {
console.log("Something went wwrong!");
} else {
console.log("It worked!");
}
}
}
//tweetIt();
setInterval(tweetIt, 60 * 1000);
I have looked over this but cannot seem to figure out what would cause the bot to repeat itself a few times instead of creating a brand new tweet,
Any help with this would be much appreciated
You're picking your tweet parts outside of your interval. Try putting this:
var statusOne = partOne.pick();
var statusEmoji = emoji.pick();
var statusTwo = partTwo.pick();
inside your tweetIt function.

Node/Javascript only send changed values

I'm writing a simple application where I send values to a mqtt broker given by a pot-meter (variable resistor). The thing I am trying to accomplish is that I only send changed values to save bandwidth. I am trying Object.observe, but that does not do anything. Can anybody help me?
My code:
var analogValue = 0;
every((0.5).second(), function() {
analogValue = my.sensor.analogRead();
var values = {values:[{key:'resistance', value: analogValue}]}
//another experiment here
var arr = ['resitance', analogValue];
Array.observe(arr, function(changes) {
console.log(changes);
});
arr[1] = analogValue
console.log('sent ',values,'to ',thingTopic)
client.publish(thingTopic, JSON.stringify(values));
});
var o = [analogValue];
Object.observe(o, function (changes) {
console.log(changes);
//eventually publish only changes to broker here
})
o.name = [analogValue]
You don't need to use Object.observe. You can just save the last measurement and check the new one against it. Like this:
// I'm assuming that any actual measurement will be different than 0
var lastMeasurement = 0;
every((0.5).second(), function() {
var analogValue = my.sensor.analogRead();
if (lastMeasurement !== analogValue) {
// the new value is different
var values = {values:[{key:'resistance', value: analogValue}]};
client.publish(thingTopic, JSON.stringify(values));
// update the last measurement value
lastMeasurement = analogValue;
}
});

Parse Cloud Code Save All

So I have a list of about 200 rows in my Parse Core. I am trying to create a job that runs through the entire list and changes the entire column of push to 0. I am trying to do so with this code:
Parse.Cloud.job("SetPush", function(request, response) {
//take in JSON with dict
var newts = new Array();
for ( var i = 0; i < request.params.push.length; i++ )
{
//add these entries to db
var DataClass = Parse.Object.extend("AllTeams");
var dataupdate = new DataClass();
var origdata = request.params.datalist[i];
dataupdate.set("push", "0");
newts[i]=dataupdate; //add another item to list
}
Parse.Object.saveAll(newts,{
success: function(list) {
// All the objects were saved.
response.success("ok " ); //saveAll is now finished and we can properly exit with confidence :-)
},
error: function(error) {
// An error occurred while saving one of the objects.
response.error("failure on saving list ");
},
});
//default body does not do response.success or response.error
});
As you can see my class is SetPush and I want to update the push column all the way down. The problem I believe lies in this:
for ( var i = 0; i < request.params.push.length; i++ )
When I run this code in the Cloud Code, it returns this error:
'TypeError: Cannot read property 'length' of undefined at main.js:43:60'
What am I doing wrong? Thank you
.length is undefined because request.params.push is an object. Looks like you want to iterate through a list you're passing in to this cloud function using the input parameter request.params.push, if/assuming the caller is passing in a valid JSON as 'push' then you can do something like this
Parse.Cloud.job("SetPush", function(request, response) {
//take in JSON with dict
var parsedJson = JSON.parse( request.params.push );
var newts = new Array();
for ( var i = 0; i < parsedJson.length; i++ )
{
//add these entries to db
var DataClass = Parse.Object.extend("AllTeams");
var dataupdate = new DataClass();
var origdata = request.params.datalist[i];
dataupdate.set("push", "0");
newts[i]=dataupdate; //add another item to list
}
Parse.Object.saveAll(newts,{
success: function(list) {
// All the objects were saved.
response.success("ok " );
//saveAll is now finished and we can properly exit with confidence :-)
},
error: function(error) {
// An error occurred while saving one of the objects.
response.error("failure on saving list ");
},
}); //default body does not do response.success or response.error
});

How to properly use Parse / Promise?

I am writing some JavaScript codes using Parse.com.
To be honest, I have been reading how to use Promise and done lots of research but cannot still figure out how to use it properly..
Here is a scenario:
I have two tables (objects) called Client and InvoiceHeader
Client can have multiple InvoiceHeaders.
InvoiceHeader has a column called "Amount" and I want a total amount of each client's InvoiceHeaders.
For example, if Client A has two InvoiceHeaders with amount 30 and 20 and Client B has got nothing, the result I want to see in tempArray is '50, 0'.
However, with the following codes, it looks like it's random. I mean sometimes the tempArray got '50, 50' or "50, 0". I suspect it is due to the wrong usage of Promise.
Please help me. I have been looking into the codes and stuck for a few days.
$(document).ready(function() {
var client = Parse.Object.extend("Client");
var query = new Parse.Query(client);
var tempArray = [];
query.find().then(function(objects) {
return objects;
}).then(function (objects) {
var promises = [];
var totalForHeader = 0;
objects.forEach(function(object) {
totalForHeader = 0;
var invoiceHeader = Parse.Object.extend('InvoiceHeader');
var queryForInvoiceHeader = new Parse.Query(invoiceHeader);
queryForInvoiceHeader.equalTo('headerClient', object);
var prom = queryForInvoiceHeader.find().then(function(headers) {
headers.forEach(function(header) {
totalForHeader += totalForHeader +
parseFloat(header.get('headerOutstandingAmount'));
});
tempArray.push(totalForHeader);
});
promises.push(prom);
});
return Parse.Promise.when.apply(Parse.Promise, promises);
}).then(function () {
// after all of above jobs are done, do something here...
});
} );
Assuming Parse.com's Promise class follows the A+ spec, and I understood which bits you wanted to end up where, this ought to work:
$(document).ready(function() {
var clientClass = Parse.Object.extend("Client");
var clientQuery = new Parse.Query(clientClass);
clientQuery.find().then(function(clients) {
var totalPromises = [];
clients.forEach(function(client) {
var invoiceHeaderClass = Parse.Object.extend('InvoiceHeader');
var invoiceHeaderQuery = new Parse.Query(invoiceHeaderClass);
invoiceHeaderQuery.equalTo('headerClient', client);
var totalPromise = invoiceHeaderQuery.find().then(function(invoiceHeaders) {
var totalForHeader = 0;
invoiceHeaders.forEach(function(invoiceHeader) {
totalForHeader += parseFloat(invoiceHeader.get('headerOutstandingAmount'));
});
return totalForHeader;
});
totalPromises.push(totalPromise);
});
return Parse.Promise.when(totalPromises);
}).then(function(totals) {
// here you can use the `totals` array.
});
});

Categories