Javascript : String Array not updating - javascript

I am trying to pass updated testvar to ComponentX
let testvar = ["Test", "Test2"];
testvar.map(test => {
test = test + "Edited";
console.log(test);//updates here
return test;
});
console.log(testvar);//doesn't retrieve updated value
<ComponentX values={testvar}>
I am aware that console isn't asynchronous but I am also passing this updated value to a component,
but original gets passed.
I tried to wrap this update as async function, like below,
let testvar = ["Test", "Test2"];
const updateFunc = async()=>{
await testvar.map(test => {
test = test + "Edited";
console.log(test);//updates here
return test;
});
}
const updatedvalues = updateFunc();
<ComponentX values={updatedvalues}>
I receive errors as promise String[] isnt acceptable on ComponentX.
Any Leads would be helpful.Thanks!

You treat to the strings as there are mutable, but actuality there not. In this case you need to update array by index
let testvar = ["Test", "Test2"];
testvar.forEach((test,i) => {
testvar[i] = test + "Edited";
console.log(test);//updates here
});
console.log(testvar);
or created a new one
testvar = testvar.map(test => {
test = test + "Edited";
console.log(test);//updates here
return test;
});

Related

React: .map method statement returns undefined

I have the following function;
const ListallSpaces = newSubject.map(mySpaces => {
const urlToBeSplit = mySpaces.s
const onlySpaceNames = urlToBeSplit.split('/')[5]
const subject = []
return (
subject.push({subject: [onlySpaceNames]}),
console.log("subject", subject)
)
})
console.log(ListallSpaces)
if i console.log(subject) it returns an array containing a certain space, which is the value i need. However, if i console.log the ListallSpaces it returns undefined. is there a reason why?
Return something.
The below example will return an array with one element. That element will be an object.
const ListallSpaces = newSubject.map(mySpaces => {
const urlToBeSplit = mySpaces.s
const onlySpaceNames = urlToBeSplit.split('/')[5]
const subject = [{subject: [onlySpaceNames]}]
return subject
})
it is giving undefined as in your return statement your push command gives 1 and console.log gives you undefined.
To make this work you have to return the subject.
just try this.
subject.push({ subject: [onlySpaceNames] }); return subject;
Because console.log returns undefined.

How to access object provided by onloadedmetadata?

Im trying to acceess a value in a object resulting from onloadedmetadata. When I console log the entire object audioDuration i can see and access the contained value. When i console log the exact element AudioDuration.length it returns undefined.
var audioDuration = {};
convertedAudio.onloadedmetadata = () => {
audioDuration.length = convertedAudio.duration
};
console.log (audioDuration) // displays object {length: 25.547755}
console.log (audioDuration.length) // displays undefined
I want to use the value of AudioDuration.length directly and not the entire object.
your problem is due to the value of audioDuration is set only in callback and the console.log is used directly after onloadedmetadata so the console.log will run before the value is set. Two ways to fix that, one way is to do console.log inside onloadmetadata. The other way is to return a promise and await for the result.
const audioDuration = {}
const getDuration = () => new Promise(resolve => {
convertedAudio.onloadedmetadata = () => {
resolve(convertedAudio.duration);
}
})
getDuration().then(l => { console.log(l); audioDuration.length = l; })
Try this
var audioDuration = {};
convertedAudio.onloadedmetadata = () => {
if(convertedAudio.duration!=undefined){audioDuration.length = convertedAudio.duration}
};
console.log (audioDuration) // displays object {length: 25.547755}
console.log (audioDuration.length) // displays idk, u see what it does since i can't replicated convertedAudio

Which type of variable is created in the code below

In the code below is an iterator:
const cart = ['Product 0','Product 1','Product 2','Product 3','Product 4','Product 5','Product 6','Product 7','Product 8','Product 9','Product 10']
function createIterator(cart) {
let i = 0;//(*)
return {
nextProduct: function() {
//i:0; (**)
let end = (i >= cart.length);
let value = !end ? cart[i++] : undefined;
return {
end: end,
value: value
};
}
};
}
const it = createIterator(cart);
First I know a copy of the present state of the function's variables and the parameters are parsed.(Right?)...
And when you run
const it = createIterator(cart);
Is a property below created?
//i:0 (**);
Making it.next(); equivalent to
{
i:0;//state or value of i from createIterator() definition;
next : function(cart){
let end = (this.i >= cart.length);
let value = !end ? cart[this.i++] : undefined;
return {
end: end,
value: value
};
}
Or does state of the value of i in line (*) from the first code, Is what's what is modified?
Please if this point is not clear... let me know to explain better.
Calling the iterator will create an instance of i scoped to the createIterator function. The object returned from it will only have access to that specific instance of i, but i is not a property of the object returned. It only can access it due to the function scope.
You can see a little better how this works if we break your code down a little more simply:
function createIterator(cart, display) {
let i = 0;
return {
next: function() {
i++;
console.log(display + ' next: ', i);
}
};
}
const cart1 = [];
const cart2 = [];
const it1 = createIterator(cart1, 'cart1');
it1.next();
it1.next();
const it2 = createIterator(cart2, 'cart2');
it2.next();
it2.next();
Each instance of the iterator has a different copy of i and only the object returned from the iterator function can access it.

Update the global variable

My code snippet first:
let GLOBAL_VAR_A = 'string1';
let GLOBAL_VAR_B = 'string2';
let GLOBAL_VAR_C = []; // Empty array
let GLOBAL_VAR_D = []; // Empty array
...
start = async () => {
...
if(...) {
await updateNews(GLOBAL_VAR_A, GLOBAL_VAR_B, GLOBAL_VAR_C, GLOBAL_VAR_D);
console.log(GLOBAL_VAR_C); // => [] (empty) (NOT OK)
console.log(GLOBAL_VAR_D); // => [object Object] = nextNews (OK!!)
...
}
};
updateNews = async (sourcePath, webResource, previousNews, nextNews) => {
previousNews = await getPreviousNews(sourcePath, previousNews);
console.log('FFF = ' + previousNews); // => FFF = [object Object] (Ok)
...
nextNews.push({
id: i + 1,
title: justGottenNews[i].title,
url: justGottenNews[i].link
});
}
getPreviousNews = async (sourcePath, previousNews) => {
let data = await fs.readFileSync(sourcePath, 'utf8');
prevNews = previousNews.concat(JSON.parse(data));
return prevNews;
};
...
My question (issue) is the following:
When I call the function updateNews() I pass there some arguments - global variables. GLOBAL_VAR_C by default is an empty array which is passed to the updateNews() function. Further this variable is passed to getPreviousNews() function. This function returns a new array (prevNews) - concatenation of the empty one and received from the file.
Then I want to re-define a value of the variable previousNews. Inside the function updateNews() its value is correct (returned array).
How can I re-define a value of passed GLOBAL_VAR_C variable further? It should be equal to previousNews. But when I console log it still empty array is returned.
Interesting point is that nextNews is updated inside updateNews() function (method push()) and GLOBAL_VAR_D is updated as well
The solution for me was to update the Global variable with push() method inside updateNews()

How to get the "returns" of functions that are arguments in a function using ...spread?

I'm developing a simple Javascript Client API for my unit tests, as I'm studying TDD and learning better by doing things.
I'm following a model where they will only be a CHECK by test, I have my TEST function, which is where all the tests of a given file will be, and each test will be called by TEST_F with only one CHECK function each, thus not needing a description for each TEST_F, since with just a CHECK, it is simple and easy to understand with just a good "nameTest".
The problem I'm having is to use the Javascript spread, I actually know well how to solve my problem without it, but I would like to understand if it could help me simplify things here. The TEST function, as I said, might get several TEST_F functions as arguments, so I thought I'd do something like const TEST = (... f) => {};, but I'm not sure how to use each "f" argument since each TEST_F function returns me an object, which I want to use to accuse the TEST_Fs that fail. I will try to explain what I try to do with the code below that we know will not work, but only to understand where I am trying to get:
/* --------------------------------------------------------------- */
/* ------------------- Test API ---------------------------------- */
/* --------------------------------------------------------------- */
const TEST = (fileName, ...f) => {
const passing = [];
const failing = [];
console.log('Running unit tests in '+fileName+':');
const tStart = performance.now();
const result = ...f(); // I know it's not possible, but you understand what I'm trying to do?
result.resultTest==='passed'?passing.push(result):failing.push(result);
const tEnd = performance.now();
const duration = tEnd - tStart;
const lenPassing = passing.length;
const lenFailing = failing.length;
console.log('Passing: '+lenPassing+' ('+duration+'ms)');
console.log('Failing: '+lenFailing);
if(lenFailing > 0){
let stg = '';
for(let i = 0; i < lenFailing; i++){
stg += (i + ') ' + failing[i].nameTest + ' (' + failing[i].durationTest + ')' + '\n');
}
console.log(stg);
}
};
const TEST_F = (nameTest, f) => {
const tStart = performance.now();
const resultTest = f();
const tEnd = performance.now();
const durationTest = tEnd - tStart;
return { nameTest: nameTest, durationTest: durationTest, resultTest: resultTest };
};
const CHECK_EQUAL = (value, expected) => {
return ((value === expected)?'passed':'failed');
};
export {
TEST,
TEST_F,
CHECK_EQUAL
};
Up 1:
How would I solve my problem without using the spread? creating a TEST object that contains an array of TEST_F and then would create a function to run the tests, something like EXECUTE_TEST, but what I want to avoid is having to call a function always in my test files, I want something simple like:
TEST("main.js",
TEST_F("test1", () => {
return CHECK_EQUAL(3, 3);
}),
TEST_F("test2", () => {
return CHECK_EQUAL(7, 3);
})
);
which I was able to solve with the #TJ Crowder answer:
for(let fn of f) {
const result = fn;
result.resultTest==='passed'?passing.push(result):failing.push(result);
}
If your goal is to call each function in the f array and get the results from them into the passing or failing arrays, I'd probably use a simple for-of:
for (const fn of f) {
const result = fn();
result.resultTest==='passed'?passing.push(result):failing.push(result);
}
or forEach or similar, any of the array looping mechanisms would do the job.

Categories

Resources