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
Related
What is the best way of creating an object of Singletons? I have a class which will be shared between different applications. This class should be a singleton PER application.
Here is what I currently have. However, when I instantiate app1 twice, it creates a new instance for that.
class Sample {
constructor(appName) { // eslint-disable-line
if (!Sample._instance[appName]) {
Sample._instance[appName] = this
console.log('Creating new instance')
this.counter = 0
}
return Sample._instance[appName]
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}
Then I call it like this:
import Sample from './sample'
const sample1 = new Sample('app1')
sample1.getVal() // OK - prints 1
sample1.getVal() // OK - prints 2
const sample1a = new Sample('app1')
sample1a.getVal() // NOK - prints 1 - should print 3
const sample2 = new Sample('app2')
sample2.getVal() // OK - prints 1
sample2.getVal() // OK - prints 2
If instead I do something like below, then how can I actually pass in appName when the instance is created already during import?
const sample = new Sample(appName)
export default sample
Just adding static _instance = {} got rid of the runtime error I encountered and made it work as you want.
I also tested this in nodejs to make sure there's not anything weird going on when importing the class instead of declaring it in the same file.
class Sample {
static _instance = {};
constructor(appName) { // eslint-disable-line
if (!Sample._instance[appName]) {
Sample._instance[appName] = this
console.log('Creating new instance')
this.counter = 0
}
return Sample._instance[appName]
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}
const sample1 = new Sample('app1')
sample1.getVal() // OK - prints 1
sample1.getVal() // OK - prints 2
const sample1a = new Sample('app1')
sample1a.getVal() // NOK - prints 1 - should print 3
const sample2 = new Sample('app2')
sample2.getVal() // OK - prints 1
sample2.getVal() // OK - prints 2
Differentiate the roles of the container object and the singleton.
Below I made an IIFE singleton container that handles creating and storing new instances of Sample and it returns an existing instance if it's already stored.
You can keep the class definitions and container singleton in their own file and export the container. Since it's already invoked in the module, you just need to call container.get('app') in the importing scripts.
class Sample {
constructor() {
console.log('Creating new instance')
this.counter = 0
}
getVal () {
this.counter++
console.log('counter: ' + this.counter)
}
}
const container = (() => {
const singletons = {};
const get = (appName) =>{
if (!singletons[appName]){
singletons[appName] = new Sample();
}
return singletons[appName]
}
return { get }
})();
let sample1 = container.get('app1')
sample1.getVal();
sample1.getVal();
let sample1A = container.get('app1')
sample1A.getVal();
let sample3 = container.get('app2')
sample3.getVal();
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
When I try to grab the object from the array, the type is undefined. Therefore I cannot use a method from the undefined object as it doesn't exist. I am relatively new to JavaScript and I have come straight from Java so the way of retrieving objects is kind of new to me. This is what I currently have.
var fleetAmount = 0;
var fleets = [];
function Fleet(number) {
this.number = number;
this.activities = [];
this.addActivity = function (activity) {
this.activities.push(activity);
};
fleets.push(this);
}
var getFleet = function(fleetNumber) {
return fleets[fleetAmount - fleetNumber];
}
This is where I try to grab the object and preform the function
const Fl = require(‘fleet.js’);
const fleet = Fl.getFleet(fleetNumber);
fleet.addActivity(activity);
I am also working in Node.js, which is how I am using the require method.
In combination with the answer from #audzzy I changed the getFleet() function so that it would be more efficient. I tested it out and it worked. This is what I used
function getFleet(fleetNumber) {
let result = fleets.filter(function (e) {
return e.number = fleetNumber;
})
return result[0];
}
Thanks for the help! I appreciate it.
you want to create a new fleet object and add it, not "this"..
adding "this" would cause a circular reference, where
this.fleets[i] = this (and all fleets would have the same value)
when calling get fleet, I would check that a fleet was returned from get fleet
in case amount is less than the number you send to getFleet (where according to what you posted: 1 returns the last, 2 returns second to last etc..)..
I hope this explanation makes sense.. anyways, this should work..
var fleets = [];
doStuff();
function doStuff(){
addFleet(1);
addFleet(2);
addFleet(7);
addFleet(3);
// should return null
let fleet1 = getFleetByNumber(5);
// should return the fleet with number 7, and not change the fleet with number 1
let fleet2 = getFleetByNumber(7);
if(fleet2){
fleet2.addActivity("activity");
}
console.log(`fleets: ${JSON.stringify(fleets)} \nfleet1: ${JSON.stringify(fleet1)} \nfleet2: ${JSON.stringify(fleet2)}`);
}
function addFleet(number) {
let fleet = { number: number,
activities: [] };
fleet.addActivity = function (activity) {
this.activities.push(activity);
};
fleets.push(fleet);
}
function getFleetByNumber(fleetNumber) {
return fleets.find(function (e) {
return e.number == fleetNumber;
});
}
function getFleet(fleetNumber) {
let result = null;
if(fleets.length - fleetNumber >= 0){
result = fleets[fleets.length - fleetNumber];
}
return result;
}
I want to create property work as a result of function, like Array.length or VideoElement.currentTime.
But I don't want to use it like function call when the object is used.
For example:
var obj = {
now : /* ??? */
}
console.log(obj.now)
Result : 2020-04-07 10:03:21
// 1 hours later
console.log(obj.now)
Result : 2020-04-07 11:03:21
// I don't want to implement like below:
console.log( obj.now() )
How can I implement it?
Make it into a getter instead of a normal function:
const obj = {
get now() {
return new Date().toString();
}
};
console.log(obj.now);
setTimeout(() => {
console.log(obj.now);
}, 1000);
You can do this using object getters:
const obj = {
get now() {
return Date.now()
}
}
console.log(obj.now)
// logs: 15870XXXXXXXX
Store the function result and then use:
Object.defineProperty()
I would need a little more on what you're trying to do.
mozilla doc I referenced
I have some function:
function funcName(first_data, SECOND_DATA) {
// ...some code here...
data: {dontMatterProp: dontMatterVal, SECOND_DATA: SECOND_DATA},
// ...some code.....
}
I need that my property name 'SECOND_DATA' changes too!
for example in php a could do something like {SECOND_DATA}...
Your question is a little unclear, but I think something like this is what you are looking for:
function funcName(first_data, SECOND_DATA_KEY, SECOND_DATA_VALUE) {
// ...some code here...
x = {}
x.data = {dontMatterProp: dontMatterVal}
x.data[SECOND_DATA_KEY] = SECOND_DATA_VALUE
// ...some code.....
}
If you just want the key to be equal to the value, you could just do
x.data[SECOND_DATA] = SECOND_DATA
But that's a little odd. Why map something to itself? No value necessary, you can just verify that the key exists if that's the case...
You can use brackets for dynamic keys in javascript. So,
var x = {}
x['something'] = 'test'
// x === { 'something': 'test' }
x[something] = 'test2'
// error: something is undefined
var something = 'hello'
x[something] = 'test3'
// x === { 'something': 'test', 'hello': 'test3' }
Hope that helps?
I think you want:
data[SECOND_DATA] = SECOND_DATA; // assign the value
If you just use:
var data = { SECOND_DATA: SECOND_DATA };
using object notation - the property name will ALWAYS be SECOND_DATA