How to access object provided by onloadedmetadata? - javascript

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

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.

updating object does not show the new property

the code in the example works fine but in my codes it doesn't
I`m trying to update object with a new property
const overrides = {paths:{"/":{}}}
const aItems = [{endpoint:"/test"}]
const mockOverrides = JSON.parse(JSON.stringify(overrides));
aItems.forEach(({endpoint}) => {
if (!mockOverrides.paths[endpoint]) {
mockOverrides.paths[endpoint] = {};
}
console.log(mockOverrides); // result {paths:{"/":{}}} expected {paths:{"/":{}, "/test":{}}}
console.log(mockOverrides.paths[endpoint]) // result is {} twice
})
as you can see the property is not displayed in the output
but is somehow exist why this happening?
After adding a ) to the end of the foreach method, it appears to be working fine:
const overrides = {paths:{"/":{}}}
const aItems = [{endpoint:"/test"}]
const mockOverrides = JSON.parse(JSON.stringify(overrides));
aItems.forEach(({endpoint}) => {
if (!mockOverrides.paths[endpoint]) {
mockOverrides.paths[endpoint] = {};
}
console.log(mockOverrides); // result {paths:{"/":{}}} expected {paths:{"/":{}, "/test":{}}}
console.log(mockOverrides.paths[endpoint]) // result is {} twice
});
Yeah. I wrote that but it was deleted. You were missing the ). Other than that the code is fine.
Maybe because the new property was set to __proto__ of mockOverrides.paths
why console.log doesn't show values of properties added by PROTOTYPES in javascript when whole object is printed?
You can reproduce it by run below code on chrome console (also get from the quote above)
var Person=function (name) {
this.Fname=name;
this.health=100;
};
var Mateen=new Person("Mateen");
console.log(Mateen);
// result: { Fname: 'Mateen', health: 100 }
Person.prototype.level=1;
console.log(Mateen);
// result: { Fname: 'Mateen', health: 100 }
console.log(Mateen.level);
// result: 1

Set arguments dynamically with Promise.all().then()

The code below works for me
Promise.all([first, second, third]).then([first, second, third] => {
console.log(second);
});
I know that console.log(second) will give me the value with the key second.
My promises are dynamically set and now it looks like below:
let collection = [second, third];
Promise.all(collection).then((collection) => {
console.log(collection);
});
In this example I set two values in collection. In real life it can include more or less values.
When I use console.log(collection) it will output collection[0] and collection[1]. In this case I don't know what which value collection[1] is.
Question
How can I, like my first example, have something like named dynamically arguments like collection['second'] or similar?
As we want to access the value dynamically, set collection to an empty object first. Then, use the keys from collection to pass all its Promise-values to Promise.all. Then, map back the fulfilled values and then, we can access collection's value by some key.
let collection = {}
for (let i = 0; i < 3; i++) {
collection[`key${i}`] = Promise.resolve(i)
}
let collectionKeys = Object.keys(collection)
Promise.all(collectionKeys.map(key => collection[key]))
.then(values => {
let collectionFulfilled = collectionKeys.reduce((obj, key, i) => {
obj[key] = values[i]
return obj
}, {})
console.log(collectionFulfilled)
})
If you pass your promises embedded inside an object with a single key, you could use that for it's name, and then with a simple helper function reverse the values & keys from this.
With the new ES6 you can then just pass like -> [{one}, {two}, {three}] etc.
Below is an example with a helper function called namedPromiseAll.
function namedPromiseAll(named) {
const pcollection =
named.map(m => Object.values(m)[0]);
const ncollection =
named.map(m => Object.keys(m)[0]);
return Promise.all(pcollection).then((c) => {
return c.reduce((a,v,ix) => {
a[ncollection[ix]] = v;
return a;
}, {});
});
}
const second = Promise.resolve(2);
const third = Promise.resolve(3);
const collection = [{second}, {third}];
namedPromiseAll(collection).then(console.log);

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()

Javascript: Array of objects, changing value in each object asynchronously

So, I know this has been asked before and I have tried other answers like .map, (function(post){ async })(value), and I am still stuck...
so, I have an array of objects and a for loop:
var postsData = [{thumbnail: www.website.com/image.jpg}, {thumbnail: www.website.com/image.jpg}, {thumbnail... etc}];
for (let i = 0; i < 3; i++) {
let thumbnail = postsData[i].thumbnail;
Cloudinary.uploader.upload(thumbnail, function(result){
// not sure what to do here
// result comes back as an object, and I want to change each thumbnail in
// the postsData array to be result.public_id
}, {transformation:[{}]});
} // go through all the items in the array
// do something with "updated" postsData array
An example would really help, as obviously, getting the values changed involves some async functions.
Set "thumbnail" property of object in array to result.public_id. Create a function where expected parameter is current object within postsData array, set "thumbnail" property of object by passing function reference to upload function, passing current object of array prop object utilizing Function.prototype.bind()
var len = postsData.length;
var n = 0;
function handleData(result, prop) {
prop["thumbnail"] = result_public.id;
if (++n === len) complete(postsData);
}
function complete(data) {
console.log(data, postsData);
}
for (let prop of postsData) {
Cloudinary.uploader.upload(
thumbnail
, handleData.bind(null, prop)
, {transformation:[{}]}
);
}
plnkr http://plnkr.co/edit/SSyUG03pyAwXMVpHdGnc?p=preview
From what I understand, you are trying to loop through an array and do async function on each of its element. What I would do is to use Promise.js (see enter link description here). So the code would look something like this:
// create an array for the promises
const PromiseArr = [];
postsData.map(d => {
PromiseArr.push(
// do async actions and push them to array
new Promise((resolve, reject) => {
Cloudinary.uploader.upload(thumbnail,(result) => {
// return the result
resolve(result);
});
})
);
})
// do all async actions and store the result in result array
const result = PromiseArr.all();

Categories

Resources