I am trying to update/create users. I created a loop for the users file and want to execute it in batches of 50 users. When I push the function to an array, the values are correct, but when the functions are executed in the array, the values are suddenly repeating.
for (const user of usersjson.users) {//Loop through new users from external systems
i++;
try {
const data = await getUser(url, okapikey, user[externalSystemId], 'externalSystemId');
if (data.users.length != 0) { //If user exists
console.log(createduser);
functions.push(()=> updateUser(url, okapikey, createduser, data.users[0].id));
} else { //If user doesn't exist
console.log(createduser);
functions.push(()=> createNewUser(url, okapikey, createduser));
};
} catch (err){
console.error(err);
}
if (functions.length == 50 || i == usersjson.users.length) {
const promises = functions.map(fn => fn()); //Run functions
const responses = await Promise.allSettled(promises);
for (const response of responses) {
//console.log(response);
if (response.status == 'fulfilled') {
if (response.value.status == 204) {
console.log(`${response.value.status}: User ${response.value.request.path.substring(7)} was updated.`);
} else {
if (response.value.status == 201 && response.value.headers.location) {
console.log(`${response.value.status}: User ${response.value.headers['location']} was created.`);
} else {
console.log(response.value.headers.location);
}
}
} else {
console.log(response);
}
}
functions=[];
}
}
//I'm not putting the get user function, as that one works fine
async function updateUser(url, token, user, userid)
{
console.log(user);
return new Promise((resolve, reject) => {
//Create headers for put request
const options = {
method: "put",
headers: {
'x-okapi-token': token,
'x-okapi-tenant':'fs00001060',
'Content-type':"application/json"
}
};
//Make API get call
user.id=userid; //Adding the required field ID to the JSON
axios.put(`${url}/users/${userid}`, JSON.stringify(user), options)
.then(response => {
if (response.status == 204) {
resolve(response);
} else {
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
}
}).catch((err) => {
if (typeof err.response.data == 'string') {
reject(`${userid}Error Code: ${err.response.status}Error Text: ${err.response.data}Status: ${err}`);
} else if (err.response.data.errors[0].message) {
console.error(`Error Text: ${err.response.data.errors[0].message}`);
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
} else {
reject(`Error Code: ${err.response.status}\nError Text: ${err.response.data.errors[0].message}\nError Status: ${err}`);
}
});
});
};
async function createNewUser (url, token, user) {
console.log(user);
return new Promise((resolve, reject) => {
//Create headers for put request
const options = {
headers: {
'X-Okapi-token': token,
'Content-type':"application/json"
}
};
//Make API get call
axios.post(`${url}/users`, JSON.stringify(user), options)
.then(response => {
if (response.status == 201) {
resolve(response);
} else {
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
}
}).catch((err) => {
console.error(`Error on ${user.externalSystemId}: ${err}`);
if (err.response.data && typeof err.response.data == 'string') {
console.error(err.response.data);
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
} else if (err.response.data.errors[0].message) {
console.error(`Error Text: ${err.response.data.errors[0].message}`);
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
} else {
reject(`Error Code: ${err.response.status}: ${user.externalSystemId},\nError Text: ${err.response.data.errors[0].message},\nError Status: ${err}`)
}
});
});
};
When I console.log(createduser) I see that different users are correctly created. For example:
{
username: 'X1',
externalSystemId: 'email1',
personal: {
lastName: 'lname1',
firstName: 'fname1',
email: 'email1'
},
id: 'id1'
}
{
username: 'X2',
externalSystemId: 'email2',
personal: {
lastName: 'lname2',
firstName: 'fname2',
email: 'email2'
},
id: 'id2'
}
However, when the console.log(user) from inside the functions themselves come in to play, suddenly the users are identical (except for the id, because that is inserted separately in the code):
{
username: 'X2',
externalSystemId: 'email2',
personal: {
lastName: 'lname2',
firstName: 'fname2',
email: 'email2'
},
id: 'id1'
}
{
username: 'X2',
externalSystemId: 'email2',
personal: {
lastName: 'lname2',
firstName: 'fname2',
email: 'email2'
},
id: 'id2'
}
It's as if the functions are not saved to the array with the parameters that are passed to them, and instead just take the parameters on the last run of the loop, and inserts them for all the functions in the array.