I'm trying to figure how can I pass an object and just check if the object is in the response using either that.includes or to.include from chai
I wrote a simple fiddle to check my problem:
https://jsfiddle.net/balexandre/4Loupnjk/2/
https://jsfiddle.net/balexandre/4Loupnjk/5/ with .deep flag
var e = {
"results": {
"total_rejected_recipients": 0,
"total_accepted_recipients": 1,
"id":"102618457586465882"
}
};
from my understanding, the e object should actually have the smaller object included... or am I missing something?
expect(e).to.include({
"results": {
"total_rejected_recipients": 0,
"total_accepted_recipients": 1
}
});
but I get the error:
assertionError: expected { Object (results) } to have property 'results' of { Object (total_rejected_recipients, total_accepted_recipients) }, but got { Object (total_rejected_recipients, total_accepted_recipients, ...) }
at Context.<anonymous> (:73:18)
First time on this framework though, might be the issue :)
First of all, you should use the deep.include assertion, as you have a deep object in there.
Anyways, it looks like this is a bug. The github ticket where this was implemented is located here and the relevant commit here.
The test coverage for this assertion is here:
expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}});
expect({foo: obj1, bar: obj2}).to.deep.include({foo: {a: 1}, bar: {b: 2}});
expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 9}});
expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {z: 1}});
expect({foo: obj1, bar: obj2}).to.not.deep.include({baz: {a: 1}});
expect({foo: obj1, bar: obj2}).to.not.deep.include({foo: {a: 1}, bar: {b: 9}});
However, it breaks in the following scenario:
expect({ foo: obj1, bar: obj2 }).to.deep.include({ foo: { a: 1 }, bar: { } });
Better open the issue in chai repository, and temporary use the chai-subset package.
Related
I would like to have an object like this:
const foo = { ... }; // how?
console.log(foo.a); // '1'
console.log(foo.a.bar); // { 'prop1': 1, 'prop2': 2 }
console.log(foo.b); // '2'
console.log(foo.b.bar); // { 'prop1': 1, 'prop2': 2 }
So, the default value of foo.a is described in the comment after the statement with the value '1'. But I would also like to go deeper into the object, to access a deeper property bar, of which a is the parent.
Something to demonstrate the desired structure:
const foo = {
a: '1',
[a.bar]: { prop1: 1, prop2: 2 },
b: '2',
[b.bar]: { prop1: 1, prop2: 2 }
}
Is this possible with TypeScript without using a function to call it? So something like this would not be a good solution for this case:
foo.a();
foo.a().bar();
Don't use this pattern.
Another version of what you seem to be asking is "Can I extend primitive types with additional properties"?
Is this possible?
Yes (sort of), but it's a code smell and I've never seen a compelling case for it. Here are two reasons why you shouldn't do it:
Anyone reviewing the code (even your future self) won't be expecting extra properties on these types, which will make it harder to read and understand.
Especially if the property names are going to be dynamic, there's a higher likelihood of overwriting/shadowing existing, standard property names on the object form of the primitive, which will almost certainly cause bugs.
With that out of the way — and, again, don't use this (you've been warned) — here's how you can do it:
References:
Object.assign()
String primitives and String objects
TS Playground
const bar = { prop1: 1, prop2: 2 };
const foo = {
a: Object.assign('one', { bar }),
b: Object.assign('two', { bar }),
};
/* The type of "foo" is:
{
a: "one" & {
bar: {
prop1: number;
prop2: number;
};
};
b: "two" & {
bar: {
prop1: number;
prop2: number;
};
};
}
*/
console.clear();
// This is a `String` (object), not a `string` (primitive):
console.log(foo.a); // String "one" { bar: { prop1: 1, prop2: 2 } }
// You can stringify it using any of these methods:
console.log(String(foo.a)); // "one"
console.log(foo.a.toString()); // "one"
console.log(`${foo.a}`); // "one"
console.log(foo.a.toUpperCase()); // "ONE"
console.log(foo.a.bar); // { prop1: 1, prop2: 2 }
console.log(foo.b); // String "two" { bar: { prop1: 1, prop2: 2 } }
console.log(String(foo.b)); // "two"
console.log(foo.b.toUpperCase()); // "TWO"
console.log(foo.b.bar); // { prop1: 1, prop2: 2 }
It would be better to devise a system for yourself of storing the value on a property on an object, (for example, as David suggested, using the value property).
Well, there's a possible solution but it's maybe not exactly what you want.
See when creating an object (for ex. a class), you have to possibility to give it a toString method. This way when the object is concatenated into a string. It executes your method instead. Here's an example:
const foo = {
a: {
prop1: 123,
prop2: 456,
toString(){
return "1" }
},
b: {
prop1: 123,
prop2: 456,
toString(){
return "1"
}
}
}
// The problem is that if you want to get the `"1"` of an object. You have to convert it into a string like for example :
console.log(`${foo.a}`)
console.log(foo.a.toString())
console.log("" + foo.a)
// And of course you can still access every possible property
console.log(foo.a.prop1)
console.log(foo.b.prop2)
console.log(foo.b.prop1 + ' - ' + foo.b)
For example I want something like:
{
a: 1,
b: 2,
c: 3
}
turned into:
{
d: {
a: 1,
b: 2,
c: 3
}
}
I've tried assigning a new property to that object with the object itself but it shows up as circular so I figure it's a reference instead of the actual properties instead of the actual values. I want to try something like JSON.stringify the object and assign it to the property but I don't know how to turn that string into an object format that I can assign to the property.
let firstObj = {
a: 1,
b: 2,
c: 3
}
let secondObj = {};
secondObj.d = firstObj;
console.log(secondObj);
Basically you create a new object and assign the original object to its property d.
You can use ES6 destructuting to make a shallow copy of the object and put it on a new prop:
let obj = {
a: 1,
b: 2,
c: 3
}
obj.d = {...obj}
console.log(obj)
If that's not an option you can reduce() over the objects keys to make a new object and assign it to d:
let obj = {
a: 1,
b: 2,
c: 3
}
obj.d = Object.keys(obj).reduce((newObj, k) => {
newObj[k] = obj[k]
return newObj
},{})
console.log(obj)
It depends whether you want to make the deep or shallow copy of the object d. (Can the object d have a nested structure?)
The question about efficient ways to clone the object has already been answered here.
I want to replace a nested object with another object.
Is this the simplest way to express that?
r.expr({ foo: {bar: 1}, eck: true })
.merge({ foo: null }, { foo: {zim: 1} })
// Expected output: { foo: {zim: 1}, eck: true }
You can use r.literal for this: https://www.rethinkdb.com/api/javascript/literal
r.expr({ foo: {bar: 1}, eck: true })
.merge({ foo: r.literal({zim: 1}) })
Hi I'm getting data from a soap service and transforming the xml to json and getting the value I need like this:
console.log(result['soap:Envelope']['soap:Body']['ns2:getFichaGeneralResponse']['return']['instituciones']['datosPrincipales']['registros'][1].valor)
is there any way to do something like this?
console.log(_.pick(result, 'registros'))
So I can get an object with the information I need?
If I understand you correctly, you have a complicated object and you want to pick some props by the specified path?
For example, you want to get { d: 'foo', e: 'bar' } by path a.b.c from the object below:
var object = {
a: {
b: {
c: {
d: 'foo',
e: 'bar',
f: 'baz'
}
}
},
g: {
h: 1
}
};
function pickPropsByPath(object, path, arrayOfPropsNames) {
return _.pick(_.get(object, path), arrayOfPropsNames);
}
console.log(pickPropsByPath(object, 'a.b.c', ['d', 'e'])) // => { d: 'foo', e: 'bar' }
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.4/lodash.min.js"></script>
I have an array of objects. During the loop I append different properties to each entry.
My question - how do I make sure every entry has all the properties of each entry?
Let's consider this:
var myArray = [{A: 1}, {B: 2}, {C: 3}];
Now I want to run some elegant one-liner to convert this array into:
[{A: 1, B:2, C: 3}, {A: 1, B:2, C: 3}, {A: 1, B:2, C: 3}]
An elegant one-liner is a bit difficult without a library. But if you have some kind of extend function, then it could be:
myArray.map(function(v) { return extend.apply(null, [{}].concat(myArray)); });
The extend function would require several objects (passed as separate arguments) to be combined. Such a function is available in jQuery as jQuery.extend, and underscore.js also has one.