I'm currently transitioning from VueJS to AlpineJS and trying to update specific JSON arrays but it doesn't seem to be updating.
An example:
Any tips or reasonings why this is not working?
var foo = [
{ id: 0, title: 'test', text: c( this ) },
{ id: 1, title: 'test', text: 'text' },
{ id: 2, title: 'test', text: 'text' },
]
function c( idk ) {
console.log( idk.title )
}
console.log(foo)
var foo = (() => {
// Paste in your original object
const foo = [ {
a: 5,
b: 6,
}
];
// Use their properties
foo.c = foo.a + foo.b;
// Do whatever else you want
// Finally, return object
return foo;
})();
console.log( foo )
These examples were from Self-references in object literals / initializers but has been modified to use an Array of JSON
The first example doesn't work for exactly the same reason as the question you referenced.
The second example doesn't work because foo is the array and not the object inside the array.
foo.a + foo.b is going to be undefined + undefined which you then assign to foo.c making foo.c Not A Number.
You then console.log the array and it doesn't show the c property because it is an array and not designed to have named properties added to it.
var foo = (() => {
const foo = [{
a: 5,
b: 6,
}];
console.log(foo.a, foo.b);
foo.c = foo.a + foo.b;
console.log(foo.c);
return foo;
})();
console.log(foo.c)
Related
Write a function that accepts any number of objects, and returns a single object that contains all the fields of the original objects.
If the same key is found in several objects, you should leave the meaning that was first met. My solution does not give the correct result.
function zip() {
const appliedValues = Object.assign({}, ...objects);
return appliedValues;
}
const objects = [
{ foo: 5, bar: 6 },
{ foo: 13, baz: -1 } // foo - repeating key
];
zip(...objects); // I expect { foo: 5, bar: 6, baz: -1 }
Make the record look like this: { foo: 5, bar: 6, baz: -1 }
enter image description here
One very quick change that would achieve this is to simply reverse the passed in array, which will result in the earlier items being used where possible.
To avoid mutating the original array, we can create a copy with [...objects] and then use .reverse() (documentation)
function zip() {
const appliedValues = Object.assign({}, ...[...objects].reverse());
return appliedValues;
}
const objects = [
{ foo: 5, bar: 6 },
{ foo: 13, baz: -1 }
];
console.log(zip(...objects));
I have an array of objects I want to destructure, retrieving both the first object and a value within it:
const [{ a }] = ([firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
]);
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
In Javascript this works; but in TypeScript this returns
Cannot find name 'firstObjectInArray'.ts(2304)
I'm trying to figure out how to type that in order to avoid the error.
As firstObjectInArray isn't part of your declaration (it's just an expression), it's an assignment to an undeclared variable.
To solve the issue, you have two ways:
Do it in two steps:
const [firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
];
const {a} = firstObjectInArray
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
Declare the firstObjectInArray earlier:
let firstObjectInArray; //<-- This can't be made `const`, as it has no initializer
const [{ a }] = ([firstObjectInArray] = [
{
a: 1,
},
{
b: 2,
},
]);
console.log(a); // 1
console.log(firstObjectInArray); // { a: 1 }
I have a code similar to this one:
let Foo = class Foo {
constructor(a) {
this.a = a.slice();
}
bar() {
this.set(0, 1, [1]);
this.set(1, 1, [1]);
}
set(x, y, n) {
this.a[x][y] = n;
}
get() {
return this.a;
}
};
module.exports = Foo;
So a property whis is a array of array, a set function that modify it, and a function that use set, and a getter.
Now I write the unit tests, with mocha:
const Foo = require('./../foo.js'),
source = [[1, 2, 3], [4, 5, 6]],
chai = require('chai'),
expect = chai.expect;
describe('Foo', () => {
describe('bar', () => {
it('expect to modify the array', () => {
let foo = new Foo(source);
foo.bar();
expect(foo.a).to.deep.equal([[1, [1], 3], [4, [1], 6]]);
});
});
describe('get', () => {
it('expect to return the array', () => {
let foo = new Foo(source);
expect(foo.get()).to.deep.equal([1, 2, 3]);
});
});
});
In which I declare the source variable at the beginning, and use it to build a new Foo each test.
However, the result is... that the bar test modify the property of the foo in the get test:
Foo
bar
✓ expect to modify the array
get
1) expect to return the array
1 passing (19ms)
1 failing
1) Foo get expect to return the array:
AssertionError: expected [ [ 1, [ 1 ], 3 ], [ 4, [ 1 ], 6 ] ] to deeply equal [ 1, 2, 3 ]
+ expected - actual
[
- [
- 1
- [
- 1
- ]
- 3
- ]
- [
- 4
- [
- 1
- ]
- 6
- ]
+ 1
+ 2
+ 3
]
at Proxy.assertEqual (node_modules/chai/lib/chai/core/assertions.js:1020:19)
at Proxy.methodWrapper (node_modules/chai/lib/chai/utils/addMethod.js:57:25)
at Context.it (test/foo.js:20:30)
Using anonymous function instead of arrow function in the mocha test doesn't change anything, using or not splice to copy the source by value either.
Did I missed something? It's obvious that I somehow attributed the same reference to the property of both foo to the same array, but I can't figure out how, and more importantly, how to ensure I can create separate the foos.
That is because this.a = a.slice() only takes a shallow copy. But as a is a nested array, changing anything in the nested arrays will be visible in both this.a and source.
You could change:
this.a = a.slice();
to:
this.a = (function deepSlice(a) {
return Array.isArray(a) ? a.map(deepSlice) : a;
})(a);
Note that your second test would need to be changed any way, since you are not comparing to what source was initialised to. So change:
expect(foo.get()).to.deep.equal([1, 2, 3]);
to:
expect(foo.get()).to.deep.equal([[1, 2, 3], [4, 5, 6]]);
I am working with JavaScript, could you help me please
Here is my problem.
I have this object:
var MyObj= [{ a: 0, b: "Zero", c: "x", d: "!" }, { a: 1, b: "One", c: "y", d: "#" }]
I want to change the element of selected object ("a" --> "id") to become like this:
var NewObj= [{ id: 0, b: "Zero", c: "x", d: "!" }, { id: 1, b: "One", c: "y", d: "#" }]
I tried to use $.map() method like this
NewObj= $.map(MyObj, function (obj) {
return { id: obj.a, b: obj.b, c: obj.c, d:obj.d };
});
Is there any better way to do this since I only change one element of object?
No need for ES6 / Object.assign, no need for jQuery:
Working Fiddle: https://jsbin.com/gosaqid/edit?js,console
function makeObj(obj){
return obj.map(function(el, i) {
el.id = i;
delete el.a;
return el;
});
}
Not unless you have a clone/copy/extend function available. One is coming up in new JavaScript, and jQuery has one, and it's not very hard writing your own. But it still isn't a walk in the park - you can't just rename a property, you need to copy and delete:
NewObj = MyObj.map(function(obj) {
var newobj = Object.assign({}, obj, {id: obj.a});
delete newobj.a;
return newobj;
});
In your example MyObj is an array of objects.
var object = {}
var array = []
var arrayOfObjects = [{}, {}, {}]
In your desired result, you have changed one of the keys of every object in the array.
Using map is a perfectly adequate way of doing this, in fact JavaScript's array has a built in map method.
var newArrayOfObjects = arrayOfObjects.map(function (obj) {
return {
id: obj.a,
b: obj.b,
c: obj.c
}
})
If you have a ton of keys this can get a little verbose so you can use $.extend, but chances are you're writing code for modern browsers so the whole thing can be written as such:
var newArrayOfObjects = arrayOfObjects.map(obj =>
Object.assign({}, obj, { id: obj.a })
)
update: as #Amadan suggests, you can also delete the old key if you need
If I have 2 type of objects:
object1 : {
value : { foo1: {}, foo2: 5 }, state: true, etc = {}
}
And
object2 : {
value : { foo1: { value: 5}, foo2: 6 }, state: true, etc = {}
}
If I do object1=object2 what exactly happens with object1 on all levels please.
I'm going to simplify that a bit:
var a = { value: 1, aStuff: true };
var b = { value: 2, bStuff: true };
b = a;
console.log(b); // { value: 1, aStuff: true }
Now a and b reference the same object. Think of it like the same object is accessible by two names. Which means this happens when you change that object:
a.value = 5
console.log(a); // { value: 5, aStuff: true }
Two names, one object.
So what happened to what to the { value: 2, bStuff: true } object? Once you tell b to reference a different object then no existing variable has a reference to it, so eventually the garbage collector will find it and dispose of it.
What happens with inner objects? That is the question..
Nothing at all. The outer object still holds references the values it contains. All that's changed is that you have two variables pointing to that same outer object.
object1 is now a reference of object2, any change in object1, will change object2;
var object1 = { foo: 'bar' };
var object2 = {
value : { foo1: { value: 5}, foo2: 6 }
};
object1 = object2; // the { foo: 'bar' } is gone.
object1.foo2 = 7; //This changes object2.foo2 value
console.log(object2.foo2); //7