adding multiple properties to object in a loop - javascript

I think my question is easy but I dont understand why my solution doesnt work :(
I'm trying to add to a new object some long properties using foreach loop but I'm getting the whole time error.
Could someone please help me?
let i = 0;
const obj = {};
for (const item of read) {
console.log(item.name);
console.log(item.imageURL);
obj['hits']['hits'] ='whyDosntWork';
console.log(item.name);
if (item.imageURL) {
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url'] =getServerURL()+item.imageURL;
} else {
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url'] ='https://cdn3.iconfinder.com/data/icons/kitchen-glyph-black/2048/4834_-_Cookbook-512.png';
}
console.log(item.imageURL);
i++;
}
I have an response and I want to mock it with my data
I wish to have for example an object that I can fill with data:
class ResponseController {
constructor() {
this.response = {
'hits': {
'hits': [{'_source.ActiveChannelReleases': [{'ImageExports': ['Resolutions']}],
}],
},
};
}
}
module.exports = ResponseController;
Will it work if I write
obj = new ResponseController();
and then I can easily add variables from the looo?

First this is a madness :).
Why is not working?
const obj = {};
you cannot do this obj['hits']['hits'] ='whyDosntWork'; due to obj['hist'] does not exists.
You need to do:
obj['hits'] = {}
and then obj['hits']['hits'] ='whyDosntWork';
And the same for the rest...
I cannot understand what do you want to do here:
obj['hits']['hits'][i]['_source.ActiveChannelReleases'][0]['ImageExports'][0]['Resolutions'][0]['Url']
But follow what I said before, you need to create each step the value you want. I can assume that you want an array in ´hits`...

The issue is that you're defining obj to be an object, and then are trying to add stuff into obj.hits without defining that as an object
const obj = {};
obj['hits'] = {}
obj['hits']['hits'] ='whyDosntWork';

Related

Custom Datatypes in JS

I'm tying to model a custom data type with JS and wondering if there's a more elegant way of doing this.
Ultimately I'd like the data type to essentially behave like an array but with an extended set of methods to meet my specific application and can be seen in the Links class below.
class Node {
constructor() {
this.links = new Links();
}
}
class Links {
constructor(node) {
this.data = [];
}
initialize() {
let initArray = [];
let maximumIncrement = hypotheticalNodeArray.length;
for (let i = 0; i < maximumIncrement ; i++) {
array[i] = 0;
}
this.data = array;
}
// More Methods Here
}
Essentially my issue is if I were to attempt to access the links data with [ node.links ] the entire object would be returned where as I'd love it just to return the data property as if the data had been accessed with [ node.links.data ].
I'm aware that just having to add that extra property isn't the end of the world, but I'd really like it if the object were to behave like an array except with an extended set of methods.
I'm not sure if this possible and I appreciate it's rather pedantic, however it would really clean the code I'm working on up.
You could define a getter that returns the internal array:
class Node {
constructor() {
// renamed “_links” because we want the getter named “links”
this._links = new Links();
}
get links () {
return this._links.data;
}
}
const node = new Node();
node.links.map( ... ) // node.links is node._links.data

Accessing Svelte component properties in a callback?

Imagine that you have a lot of properties in a component:
let a = 'foo';
let b = 'bar';
// ...
let z = 'baz';
You then want to do something like update all of them from an external callback, like in another library (i.e. something that isn't and can't be a Svelte component itself).
A simple use case is just an AJAX method to load in a bunch of data (assume this ajax function works and you can pass it a callback):
onMount(async function() {
ajax('/data', function(data) {
a = data.a;
b = data.b;
// ...
z = data.z;
});
});
This works, but it's incredibly boilerplaty. What I'd really like is a way to loop through all the properties so they can be assigned to programmatically, especially without prior knowledge on the outside library/callback's part.
Is there no way to get access to a Svelte component and its properties so you can loop through them and assign them from an outside function?
Vue has a simple solution to this, because you can pass the component around, and still check and assign to its properties:
var vm = this;
ajax('/data', function(data) {
for (var key in data) {
if (vm.hasOwnProperty(key)) {
vm[key] = data[key];
}
});
});
I have seen some solutions to this, but they're all outdated - none of them work with Svelte 3.
Apologies if this has been asked before. I've spent days trying to figure this out to avoid all that extra boilerplate and the closest I could find is Access Component Object in External Callback? which does not have an answer right now.
If possible, you could put the ajax call in the parent component and have the data returned from it stored in a temporary object, that you then pass on to the component using the spread operator.
<Component { ...dataObject }></Component>
let dataObject = {};
onMount(async function() {
ajax('/data', function(data) {
dataObject = data;
});
});
You can reduce the boilerplate by using destructuring:
onMount(async function() {
ajax('/data', data => {
({ a, b, ..., z } = data);
});
});
But if you have a very large number of variables, you might be better off just putting them in an object in the first place:
let stuff;
onMount(async function() {
ajax('/data', data => {
stuff = data;
});
});

Why does mutating one property (Object) also change in a different and separately declared property?

I have 2 properties declared like so:
ngOnInit() {
this.defaultRequirements = myData.property1.countryDocument; //should never change
this.filteredRequirements = myData.property1.countryDocument;
}
When I run this onFilter function, the defaultRequirements property also gets mutated.
onFilter(selectedSections) {
let index = -1;
this.defaultRequirements.forEach(country => {
index++;
const filteredSectionsList = [];
country.section.forEach(section => {
selectedSections.value.forEach(selectedSelection => {
const selection = selectedSelection.split(/\s*[-]\s*/);
if (country.countryCode === selection[0]) {
console.log('matched');
filteredSectionsList.push(section);
}
});
const countryObj = Object.assign({}, country, {
section: [...filteredSectionsList]
})
// Here is the issue, when filtering, this.defaultRequirements also gets changed!
this.filteredRequirements[index] = countryObj;
})
})
}
The Problem
I don't understand how mutating this.filteredRequirements is ALSO mutating this.defaultRequirements (they both equal the same thing)! How can I avoid this behaviour and have defaultRequirements be unaffected by changes done on filteredRequirements?
Okay, so your declared object myData.property1.countryDocument is a non-primitive/reference value. So that means that both this.defaultRequirements and this.filteredRequirements are pointing to literally the same piece of data.
If you were to do this with a primitive value (eg: a string), you would get a copy; so this.defaultRequirements and this.filteredRequirements would be completely separate and could be manipulated with no effect on each other.
To duplicate/copy an object in the way that you intended is totally possible and there's been a lot of discussion about it already which I won't duplicate; I'd suggest you take a look at this which covers it nicely.
Try this:
ngOnInit() {
this.defaultRequirements = JSON.parse(JSON.stringify(myData.property1.countryDocument));
this.filteredRequirements = JSON.parse(JSON.stringify(myData.property1.countryDocument));
}
or
ngOnInit() {
this.defaultRequirements = {...myData.property1.countryDocument}
this.filteredRequirements = {...myData.property1.countryDocument}
}

javascript - how to get object from array, and use its methods?

i have a problem using a class methods, after it was inserted into array. when i pull it back i can no longer use it methods.
and i know javascript does not have class, when i say class i mean object -or js equal.
suppose i have the following:
// a simple atomic class
function raw_msg(msg) {
this.msg = msg;
this.print = function () {
console.log(this.msg);
}
}
// and then i have this container for this "atomic" class
// which accept array of unknown object (known to me though..) = in_buffer
// i.e in_buffer is just an array of objects (one type of object)
function buffer(in_buffer) {
this.trans_buffer = null;
if (in_buffer!=null)
this.set_buffer (in_buffer);
this.set_buffer = function (buffer) {
this.trans_buffer = [];
var length = buffer.length,
row, new_raw_msg;
for(var x = 0; x < length; x++) {
row = buffer[x];
this.trans_buffer.push(new raw_msg(row));
}
console.log(this.trans_buffer);
}
this.use_some_raw_msg_method = function () {
var firstrow = this.trans_buffer[0];
firstrow.print(); // here is the problem!!!
//this here where i need help as it yield the error:
//Uncaught TypeError: Object #<Object> has no method 'print'
}
}
// this is how i use it, this code sits in a diffrent yet another class...
// this here im just building fake array
var buffer_in = [];
for (var x=0;x<10;x++)
buffer_in.push ("whatever" + x);
this.trans_buffer = new trans_helper(buffer_in);
this.trans_buffer.use_some_raw_msg_method (); // will yield the error as described
i hope this here, is clear, ask away if you need clarifications.
thanks for your help!
note to future readers - there is no problem in retrieving an object and using its methods.
You had several problems with your code.
Associative array does not have .push() method so the following line failed:
buffer_in.push ("whatever" + x);
To fix this just declare plain array:
var buffer_in = [];
You tried to create instance of function called trans_helper which does not exist. The name is buffer instead, so fix would be:
var trans_buffer = new buffer(buffer_in);
Last but not least, you tried to call function in the "class" when it still did not exist yet. JavaScript does not "compile" functions in advance, when inside function it will go line by line. So in this line in your code:
this.set_buffer (in_buffer);
There was still no function called "set_buffer" in your class. To fix this, place the function declaration above, on top.
Live test case.

Access object in array which is a property of another object - Javascript

It's been a long time since I learned OOP and I'm new to JS, so things might look weird for more advanced users - sorry :)
function page(title) {
this.subPages = [];
this.title = title;
}
page.prototype.addToSubPages = function(subPage) {
this.subPages.push(subPage);
}
page.prototype.getSubPages = function() {
return this.subPages;
}
Now I create 2 objects:
startPage = new page("start");
somePage = new page("foo");
...and try to add somePage into the array in startPage:
startPage.addToSubPages(somePage);
Now this doesn't seem to work, although it should be correct, if I'm not mistaken.
console.log(startPage.getSubPages());
This shows me that something is in the array, but the object appears to be empty. What am I doing wrong?
Also: How would I access a certain element in that array? Like this: startPage.getSubPages()[0].getFoo();?
Edit: Holy Mackerel, Batman! This is more like my actual code: http://jsfiddle.net/pZHKS/2/
You're all right, the code I posted actually works. As soon as inheritance comes into play, it doesn't work anymore. Why, though? It should work exactly like the code above, right?
function page(title) {
this.title = title;
}
function subPage() {
this.contentPages = [];
}
subPage.prototype = new page;
There are two problems.
your not calling page in subPage.
your using Child.prototype = new Parent; that's wrong, use Object.create instead
So the fixed code would be.
function page(title) {
this.title = title;
}
function subPage(title) {
page.call(this, title);
this.contentPages = [];
}
subPage.prototype = Object.create(page.prototype);

Categories