I am playing around with binance API, im very new to javascript, the first section in my code
binance.prices((error, ticker) => {
console.log("prices()", ticker);
console.log("Price of BTC: ", ticker.BTCUSDT);
});
above code outputs:
ETHBTC: '0.07421500',
LTCBTC: '0.01994000',
BNBBTC: '0.00110540',
NEOBTC: '0.00853400',
QTUMETH: '0.02604400',
the code below runs a check on an selected key (GTOBTC), I cant seem to be able to create a loop which takes the name from the keys above.
binance.depth("GTOBTC", (error, depth, symbol) => {
a = 0;
b = 0;
for (value in depth.bids){
a += Number(value);
};
for (value in depth.asks){
b += Number(value);
};
var c = a - b;
var d = (c / a) * 100;
if (d >= 2.0){
console.log(symbol + " Percent ok");
console.log(d);
} else {
console.log(symbol + " percentage not sufficient");
}
})
output for code above:
GTOBTC percentage not sufficient
Any help would be great thanks.
You can use Object.keys as below:
Object.keys(object).map((key) => {
console.log(object[key])
});
or when you have jquery in web, u can use this:
$.each(object, function(key, value) {
console.log(key + ' ' + value);
});
Related
I need a js sum function to work like this:
sum(1)(2) = 3
sum(1)(2)(3) = 6
sum(1)(2)(3)(4) = 10
etc.
I heard it can't be done. But heard that if adding + in front of sum can be done.
Like +sum(1)(2)(3)(4). Any ideas of how to do this?
Not sure if I understood what you want, but
function sum(n) {
var v = function(x) {
return sum(n + x);
};
v.valueOf = v.toString = function() {
return n;
};
return v;
}
console.log(+sum(1)(2)(3)(4));
JsFiddle
This is an example of using empty brackets in the last call as a close key (from my last interview):
sum(1)(4)(66)(35)(0)()
function sum(firstNumber) {
let accumulator = firstNumber;
return function adder(nextNumber) {
if (nextNumber === undefined) {
return accumulator;
}
accumulator += nextNumber;
return adder;
}
}
console.log(sum(1)(4)(66)(35)(0)());
I'm posting this revision as its own post since I apparently don't have enough reputation yet to just leave it as a comment. This is a revision of #Rafael 's excellent solution.
function sum (n) {
var v = x => sum (n + x);
v.valueOf = () => n;
return v;
}
console.log( +sum(1)(2)(3)(4) ); //10
I didn't see a reason to keep the v.toString bit, as it didn't seem necessary. If I erred in doing so, please let me know in the comments why v.toString is required (it passed my tests fine without it). Converted the rest of the anonymous functions to arrow functions for ease of reading.
New ES6 way and is concise.
You have to pass empty () at the end when you want to terminate the call and get the final value.
const sum= x => y => (y !== undefined) ? sum(x + y) : x;
call it like this -
sum(10)(30)(45)();
Here is a solution that uses ES6 and toString, similar to #Vemba
function add(a) {
let curry = (b) => {
a += b
return curry
}
curry.toString = () => a
return curry
}
console.log(add(1))
console.log(add(1)(2))
console.log(add(1)(2)(3))
console.log(add(1)(2)(3)(4))
Another slightly shorter approach:
const sum = a => b => b? sum(a + b) : a;
console.log(
sum(1)(2)(),
sum(3)(4)(5)()
);
Here's a solution with a generic variadic curry function in ES6 Javascript, with the caveat that a final () is needed to invoke the arguments:
const curry = (f) =>
(...args) => args.length? curry(f.bind(0, ...args)): f();
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1)() == 5 // true
Here's another one that doesn't need (), using valueOf as in #rafael's answer. I feel like using valueOf in this way (or perhaps at all) is very confusing to people reading your code, but each to their own.
The toString in that answer is unnecessary. Internally, when javascript performs a type coersion it always calls valueOf() before calling toString().
// invokes a function if it is used as a value
const autoInvoke = (f) => Object.assign(f, { valueOf: f } );
const curry = autoInvoke((f) =>
(...args) => args.length? autoInvoke(curry(f.bind(0, ...args))): f());
const sum = (...values) => values.reduce((total, current) => total + current, 0)
curry(sum)(2)(2)(1) + 0 == 5 // true
Try this
function sum (...args) {
return Object.assign(
sum.bind(null, ...args),
{ valueOf: () => args.reduce((a, c) => a + c, 0) }
)
}
console.log(+sum(1)(2)(3,2,1)(16))
Here you can see a medium post about carried functions with unlimited arguments
https://medium.com/#seenarowhani95/infinite-currying-in-javascript-38400827e581
Try this, this is more flexible to handle any type of input. You can pass any number of params and any number of paranthesis.
function add(...args) {
function b(...arg) {
if (arg.length > 0) {
return add(...[...arg, ...args]);
}
return [...args, ...arg].reduce((prev,next)=>prev + next);
}
b.toString = function() {
return [...args].reduce((prev,next)=>prev + next);
}
return b;
}
// Examples
console.log(add(1)(2)(3, 3)());
console.log(+add(1)(2)(3)); // 6
console.log(+add(1)(2, 3)(4)(5, 6, 7)); // 28
console.log(+add(2, 3, 4, 5)(1)()); // 15
Here's a more generic solution that would work for non-unary params as well:
const sum = function (...args) {
let total = args.reduce((acc, arg) => acc+arg, 0)
function add (...args2) {
if (args2.length) {
total = args2.reduce((acc, arg) => acc+arg, total)
return add
}
return total
}
return add
}
document.write( sum(1)(2)() , '<br/>') // with unary params
document.write( sum(1,2)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)() , '<br/>') // with unary params
document.write( sum(1)(2,3)() , '<br/>') // with binary params
document.write( sum(1)(2)(3)(4)() , '<br/>') // with unary params
document.write( sum(1)(2,3,4)() , '<br/>') // with ternary params
ES6 way to solve the infinite currying. Here the function sum will return the sum of all the numbers passed in the params:
const sum = a => b => b ? sum(a + b) : a
sum(1)(2)(3)(4)(5)() // 15
function add(a) {
let curry = (b) => {
a += b
return curry;
}
curry[Symbol.toPrimitive] = (hint) => {
return a;
}
return curry
}
console.log(+add(1)(2)(3)(4)(5)); // 15
console.log(+add(6)(6)(6)); // 18
console.log(+add(7)(0)); // 7
console.log(+add(0)); // 0
Here is another functional way using an iterative process
const sum = (num, acc = 0) => {
if !(typeof num === 'number') return acc;
return x => sum(x, acc + num)
}
sum(1)(2)(3)()
and one-line
const sum = (num, acc = 0) => !(typeof num === 'number') ? acc : x => sum(x, acc + num)
sum(1)(2)(3)()
You can make use of the below function
function add(num){
add.sum || (add.sum = 0) // make sure add.sum exists if not assign it to 0
add.sum += num; // increment it
return add.toString = add.valueOf = function(){
var rtn = add.sum; // we save the value
return add.sum = 0, rtn // return it before we reset add.sum to 0
}, add; // return the function
}
Since functions are objects, we can add properties to it, which we are resetting when it's been accessed.
we can also use this easy way.
function sum(a) {
return function(b){
if(b) return sum(a+b);
return a;
}
}
console.log(sum(1)(2)(3)(4)(5)());
To make sum(1) callable as sum(1)(2), it must return a function.
The function can be either called or converted to a number with valueOf.
function sum(a) {
var sum = a;
function f(b) {
sum += b;
return f;
}
f.toString = function() { return sum }
return f
}
function sum(a){
let res = 0;
function getarrSum(arr){
return arr.reduce( (e, sum=0) => { sum += e ; return sum ;} )
}
function calculateSumPerArgument(arguments){
let res = 0;
if(arguments.length >0){
for ( let i = 0 ; i < arguments.length ; i++){
if(Array.isArray(arguments[i])){
res += getarrSum( arguments[i]);
}
else{
res += arguments[i];
}
}
}
return res;
}
res += calculateSumPerArgument(arguments);
return function f(b){
if(b == undefined){
return res;
}
else{
res += calculateSumPerArgument(arguments);
return f;
}
}
}
let add = (a) => {
let sum = a;
funct = function(b) {
sum += b;
return funct;
};
Object.defineProperty(funct, 'valueOf', {
value: function() {
return sum;
}
});
return funct;
};
console.log(+add(1)(2)(3))
After looking over some of the other solutions on here, I would like to provide my two solutions to this problem.
Currying two items using ES6:
const sum = x => y => (y !== undefined ) ? +x + +y : +x
sum(2)(2) // 4
Here we are specifying two parameters, if the second one doesnt exist we just return the first parameter.
For three or more items, it gets a bit trickier; here is my solution. For any additional parameters you can add them in as a third
const sum = x => (y=0) => (...z) => +x + +y + +z.reduce((prev,curr)=>prev+curr,0)
sum(2)()()//2
sum(2)(2)()//4
sum(2)(2)(2)//6
sum(2)(2)(2,2)//8
I hope this helped someone
I'm attempting to write a webpage that presents the user with two options from a list and asks them which is better. I repeat this until the list is sorted. I am having trouble understanding how I can do this in javascript. I've tried a few things, but none of them have worked yet.
If this was in, say, C++, I would just write a class and then overload the < operator to ask for user input via cin or whatever, but that doesn't really work in a webpage. I'm attempting something similar with:
class Character {
constructor(initName, initPicture, initColor) {
this.name = initName;
this.picture = initPicture;
this.color = initColor;
}
async set1() {
console.log("should display " + this.name);
document.getElementById("pic1").src = this.picture;
document.getElementById("name1").innerHTML = this.name;
document.getElementById("character1").style.background = this.color;
console.log("displayed " + this.name);
}
async set2() {
console.log("should display " + this.name);
document.getElementById("pic2").src = this.picture;
document.getElementById("name2").innerHTML = this.name;
document.getElementById("character2").style.background = this.color;
console.log("displayed " + this.name);
}
}
var decision = false;
async function compare(a, b) {
console.log("comparing " + a.name + " to " + b.name);
a.set1();
b.set2();
console.log("after display");
const nameA = a.name;
const nameB = b.name;
/*while (!decision) {
}*/
// var result = prompt("Who is better, " + a.name + " or " + b.name
+ "?");
let comparison = 0;
if (result === nameA) {
comparison = 1;
}
else if (result === nameB) {
comparison = 0;
}
console.log(comparison);
return comparison;
}
Essentially, the two commented lines were two ways of trying to see what would happen if the function was stalled. When this happens, nothing is rendered to the screen via set1 or set2 (which I know are called because of the console.log).
Eventually, I plan to store the result of the comparison in a database and check to see if the comparison has already been made first. The user will choose through clicking on one of the divs (not implemented yet).
I'm not really looking to 'debug' my code per-se since it technically works; I'm just not sure how to approach this problem. I don't think that the way I am doing it now is the best.
By the way, I'm not using the library sort function since it doesn't like async functions.
What kind of algorithm/srtucture would you use to write a webpage that sorts a list based on the user choosing which is greater?
Everything you do in javascript is somehow async (except promt), so you just have to make it possible to await the user clicking one of the divs. For that we just build a Promise that resolves when the click event occurs on a certain element:
function wasClicked(el) {
return new Promise((resolve) => {
el.addEventListener("click", function handler() {
el.removeEventListener("click", handler);
resolve(el);
});
});
}
Then you can change your comparison to:
static async function compare(a, b) { // <- should be static
console.log("comparing " + a.name + " to " + b.name);
a.set1();
b.set2();
console.log("after display");
const pic1 = document.getElementById("pic1");
const pic2 = document.getElementById("pic2");
const choice = await Promise.race(wasClicked(pick), wasClicked(pic2));
return choice === pic1 ? 1 : -1;
}
Now we only need a way to sort an array asynchronoulsy, but thats quite easy:
async function asyncSort(array, comparator) {
for(let i = 0; i < array.length - 1; i++) {
if(await comparator(array[i], array[i + 1]) < 0) {
([array[i], array[i + 1]] = [[array[i + 1], array[i]]);
i -= 2;
}
}
}
So you can now do:
asyncSort(someArray, Character.compare);
PS: classes should by convention just contain methods that are "traits" of the class, e.g. Character.speak(), neither set1 nor set2 do that so they should not be methods of Character
Say I have an object instance like this :
var objectA = {"a": 1, "b": 2, "c" : 3};
and in my code I access the property like this:
cc.log(objectA.a); // output 1
now I want to add a get/set for this object to provide some simple encrypt/decrypt feature:
hookSetGet: function (someObject) {
for (var key in someObject) {
cc.log("key: " + key);
// store the origin value before Object.defineProperty
var pureValue = someObject[key];
// add a property to store the encrypted value
var hiddenValueKey = "__" + key;
someObject[hiddenValueKey] = undefined;
Object.defineProperty (
someObject,
key,
{
set: function (val) {
// simulate encrypt
this.hiddenValueKey = val + 1;
cc.log("hooked set: " + val + " - " + this.hiddenValueKey);
},
get: function () {
cc.log("hooked get: " + this.hiddenValueKey + " - " + (this.hiddenValueKey - 1));
// simulate decrypt
return this.hiddenValueKey - 1;
}
}
);
// trigger set to encrypt
someObject[key] = pureValue;
}
}
but when I test the function like this:
var objectA = {"a": 1, "b": 2, "c" : 3};
this.hookSetGet(objectA);
cc.log(objectA.a);
cc.log(objectA.b);
cc.log(objectA.c);
I do not get the result I want :
key: a
hooked set: 1 - 2
key: b
hooked set: 2 - 3
key: c
hooked set: 3 - 4
hooked get: 4 - 3
3
hooked get: 4 - 3
3
hooked get: 4 - 3
3
It seems like even when I call
objectA.a
I will get the value of
objectA.c
The problem seems quite simple but I just can not figure out where is wrong.
Any suggestion will be appreciated, thanks :)
UPDATE:
I tried the following code without change the code of hookSetGet :
cc.log(objectA.__a);
cc.log(objectA.__b);
cc.log(objectA.__c);
and get:
undefined
undefined
undefined
Then I changed the hookSetGet function:
set: function (val) {
// simulate encrypt
someObject[hiddenValueKey] = val + 1;
cc.log("hooked set: " + val + " - " + someObject[hiddenValueKey]);
},
get: function () {
cc.log("hooked get: " + someObject[hiddenValueKey] + " - " + (someObject[hiddenValueKey] - 1));
// simulate decrypt
return someObject[hiddenValueKey] - 1;
}
I changed all the this.hiddenValueKey to someObject[hiddenValueKey].
and the output is :
cc.log(objectA.__a); // 2 good
cc.log(objectA.__b); // 3 good
cc.log(objectA.__c); // 4 good
cc.log(objectA.a); // hooked get: 4 - 3 still wrong
cc.log(objectA.b); // hooked get: 4 - 3 still wrong
cc.log(objectA.c); // hooked get: 4 - 3 still wrong
So, you wrote this:
Object.defineProperty (
someObject,
key,
{
set: function (val) {
// simulate encrypt
this.hiddenValueKey = val + 1;
cc.log("hooked set: " + val + " - " + this.hiddenValueKey);
},
get: function () {
cc.log("hooked get: " + this.hiddenValueKey + " - " + (this.hiddenValueKey - 1));
// simulate decrypt
return this.hiddenValueKey - 1;
}
}
);
In your getter and setter this from this.hiddenValueKey refers to your objectA Object in all cases, not to each property. So when you want to set a value for each property you're actually over-writing objectA.hiddenValueKey. This is why when you try to get back the values you only get the last value which was set.
Even though you set hiddenValueKey to be unique, in the getter and setter you acess the same property. This is because this.hiddenValueKey is the same as writing this['hiddenValueKey']. Did you mean to write this[hiddenValueKey] ? Even if you do it, you might have some scoping issues with the hiddenValueKey always having the latest key value after you exit the loop.
So, you can try this:
Object.defineProperty (
someObject,
key,
{
set: function (val) {
// simulate encrypt
this[hiddenValueKey] = val + 1;
cc.log("hooked set: " + val + " - " + this[hiddenValueKey]);
},
get: function () {
cc.log("hooked get: " + this[hiddenValueKey] + " - " + (this[hiddenValueKey] - 1));
// simulate decrypt
return this[hiddenValueKey] - 1;
}
}
);
But, as I said, you might have to create a closure for the hiddenValueKey variable so it will be unique for each property getter and setter.
You can create a closure like this:
(function(hiddenValueKey) {
Object.defineProperty (
someObject,
key,
{
set: function (val) {
// simulate encrypt
this[hiddenValueKey] = val + 1;
cc.log("hooked set: " + val + " - " + this[hiddenValueKey]);
},
get: function () {
cc.log("hooked get: " + this[hiddenValueKey] + " - " + (this[hiddenValueKey] - 1));
// simulate decrypt
return this[hiddenValueKey] - 1;
}
}
);
}(hiddenValueKey));
There are several issues with your code. One of them is that key and hiddenValueKey are set in the scope of the hookGetSet function. Therefore whenever you use them, you use the last value in the loop (3 and __c). You can fix this in two ways:
use let instead of var to define key and hiddenValueKey within the loop scope, but that only works in ES6
use a closure to scope the inside of the loop
The other problem is that inside the properties you use this.hiddenValueKey, which is the same as this['hiddenValueKey'], not this[hiddenValueKey] as I assume you intended.
Here is code that works (EcmaScript6):
hookSetGet : function (someObject) {
for (let key in someObject) {
cc.log("key: " + key);
// store the origin value before Object.defineProperty
var pureValue = someObject[key];
// add a property to store the encrypted value
let hiddenValueKey = "__" + key;
someObject[hiddenValueKey] = undefined;
Object.defineProperty(
someObject,
key, {
set : function (val) {
// simulate encrypt
this[hiddenValueKey] = val + 1000;
cc.log("hooked set: " + val + " - " + this[hiddenValueKey]);
},
get : function () {
// simulate decrypt
var result = this[hiddenValueKey] - 1000;
cc.log("hooked get: " + this[hiddenValueKey] + " - " + result);
return result;
}
});
// trigger set to encrypt
someObject[key] = pureValue;
}
}
and here is same code for classic ES5 Javascript:
hookSetGet : function (someObject) {
for (var k in someObject) {
(function () {
var key = k;
cc.log("key: " + key);
// store the origin value before Object.defineProperty
var pureValue = someObject[key];
// add a property to store the encrypted value
var hiddenValueKey = "__" + key;
someObject[hiddenValueKey] = undefined;
Object.defineProperty(
someObject,
key, {
set : function (val) {
// simulate encrypt
this[hiddenValueKey] = val + 1000;
cc.log("hooked set: " + val + " - " + this[hiddenValueKey]);
},
get : function () {
// simulate decrypt
var result = this[hiddenValueKey] - 1000;
cc.log("hooked get: " + this[hiddenValueKey] + " - " + result);
return result;
}
});
// trigger set to encrypt
someObject[key] = pureValue;
})();
}
}
I am trying to learn graphs well and implemented the following depth-first search in javascript. The DFS function is working ok, but the checkRoutes function is the source of my troubles. The checkRoutes function accepts two inputs and returns true if there is a possible path between two nodes/vertices, and false if not. it does this by starting at a node, checking the adjacency list, and then checking the adjacency lists of every item in the adjacency list via recursion.
My solution works for only one case - when you check two vertices once, but due to the way I'm storing the possibleVertices array globally, "possibleVertices" doesn't get cleared out each time. how could I push and store to the "possibleToVisit" array inside "checkRoute" instead of globally in this class? Would it be better to have this array stored on the constructor?
var possibleToVisit = [];
function dfs(v) {
this.marked[v] = true;
if (this.adj[v] !== undefined) {
console.log("visited vertex " + v);
}
for (var i = 0; i < this.adj[v].length; i++) {
var w = this.adj[v][i];
if (!this.marked[w]) {
possibleToVisit.push(w)
this.dfs(w);
}
}
console.log(possibleToVisit);
}
function checkRoute(v, v2) {
this.dfs(v);
if (possibleToVisit.indexOf(v2) === -1) {
return false;
}
return true;
}
g = new Graph(5);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 3);
g.addEdge(2, 4);
// g.showGraph();
// g.dfs(0);
console.log(g.checkRoute(0, 4));//true
console.log(g.checkRoute(0, 5));//false
https://jsfiddle.net/youngfreezy/t1ora6ab/3/#update
You can write a DFS "starter" function, which will reset all variables, and return something if necessary:
function Graph(v) {
this.startDfs = startDfs;
this.possibleToVisit = [];
}
// ...
function startDfs(v) {
this.possibleToVisit = []; // here, you can reset any values
this.dfs(v);
return true; // here, you can return a custom object containing 'possibleToVisit'
}
And call it only using startDfs:
function checkRoute(v, v2) {
this.startDfs(v);
if (this.possibleToVisit.indexOf(v2) === -1) {
return false;
}
return true;
}
Here is the updated JSFiddle.
Arrays in Javascript get passed as reference, so something like
function fill(a,l){
for(var i = 0;i<l;i++)
a.push(i + 10);
}
function check(idx, max){
var arr = [];
fill(arr,max);
console.log(arr[idx]); // 14
}
check(4,10)
would work and everytime check gets called arr is fresh and clean.
You can use a marked[] array (which is filled up during the dfs() call) to determine whether a particular vertex can be reached from a known vertex s.
Please take a look at the depth first search implementation in the following library:
https://github.com/chen0040/js-graph-algorithms
It provides an object oriented approach to the graph creation as well as the depth first search algorithm.
The sample code for its depth first search algorithm is given here:
var jsgraphs = require('js-graph-algorithms');
var g = new jsgraphs.Graph(6);
g.addEdge(0, 5);
g.addEdge(2, 4);
g.addEdge(2, 3);
g.addEdge(1, 2);
g.addEdge(0, 1);
g.addEdge(3, 4);
g.addEdge(3, 5);
g.addEdge(0, 2);
var starting_vertex = 0;
var dfs = new jsgraphs.DepthFirstSearch(g, starting_vertex);
for(var v=1; v < g.V; ++v) {
if(dfs.hasPathTo(v)) {
console.log(s + " is connected to " + v);
console.log("path: " + dfs.pathTo(v));
} else {
console.log('No path from ' + s + ' to ' + v);
}
}
On Parse.com I have the following function, and my question follows:
function myFunction(array, value) {
var logMessage;
logMessage = "array: " + array.length.toString();
console.log(logMessage);
if (!array.length) return;
if (!value) value = Math.min(10, array.length);
if (array[array.length - 1].get("advertisePointNumber") >= value) return;
var classPromise;
array[array.length - 1].set("advertisePointNumber", value);
logMessage = "(BIS)array: " + array.length.toString();
console.log(logMessage);
classPromise = (array[array.length - 1].save(null, {}).then(function (object) {
logMessage = "HERE I AM!!!";
console.log(logMessage);
if (array.length == 1) return;
array.splice(array.length - 1, 1);
return myFunction(array, value);
}, function (error) {
// saving the object failed.
console.log("error:" + error);
}));
logMessage = "(TER)array: " + array.length.toString();
console.log(logMessage);
return Parse.Promise.when(classPromise);
}
The question is what am I missing? I never see the message "HERE I AM!!!" (and no error either) in the logs and as a consequence the recursive call that I wish is not working.
I have successfully used similar code in the past, when reading data. Here I am saving data. I must be doing something the wrong way. What is it?
Update to the question:
Calling this function with the following line of code:
myFunction(myArray, 0);
I get the log below:
I2015-06-22T07:05:34.160Z]myArray: 2 // Number of elements in the initial Array.
I2015-06-22T07:05:34.161Z]array: 2
I2015-06-22T07:05:34.162Z](BIS)array: 2
I2015-06-22T07:05:34.163Z](TER)array: 2
I would expect to see :
I2015-06-22T07:0.....]array: 1
after the above but I do not see anything.
Instead of going for recursive, you can try this:
classPromise = array.map(function(obj){ return obj.save();});
in es6, same thing can be:
classPromise = array.map(obj => obj.save());
Edit
You can reduce the whole function to:
function myFunction(array, value) {
if ( !array || !array.length) return;
console.log("array: " + array.length);
if (!value) value = Math.min(10, array.length);
var pSave=[], i = array.length, v2=(value)? value : Math.min(10, i);
while(i>0 && array[i-1].get("advertisePointNumber") >= value){
array[i - 1].set("advertisePointNumber", value);
pSave.push(array[i - 1].save());
console.log("(BIS)array: " + i);
i--;
v2=(value)? value : Math.min(10, i);
}
return Parse.Promise.when(pSave);
}
if you wanted it to be saved sequentially,
...
var pSave = Parse.Promise.as(1),
...
pSave.then(function(){
return array[i-1].save();
});
...
return pSave;
}
You don't need to pass null as the 1st parameter
You don't need to use both save with options (2nd parameter), and save with promises chain (.then)
So, just remove both the first and the second parameter of save function as follows
array[array.length - 1].save().then(...
Updated Answer
You should use multiple save calls in promises chain instead of recursive one like the below
function myFunction(array, value) {
var logMessage;
logMessage = "array: " + array.length.toString();
console.log(logMessage);
if (!array.length) return;
if (!value) value = Math.min(10, array.length);
var savePromises = Parse.Promise.as();
array.map(function(element, index) {
// Calculate value based on your needs
if(element.get("advertisePointNumber") < value) {
element.set("advertisePointNumber", value);
}
savePromises = savePromises.then(function() {
return element.save();
});
});
return savePromises.then(function (object) {
logMessage = "HERE I AM!!!";
console.log(logMessage);
}, function (error) {
// saving the object failed.
console.log("error:" + error);
});
}
OR if you have the option to make cloud code to save them in one request, you should do, to reduce network requests