finding an object by key using lodash - lodash

I have a json object like this
var variable = {
a : { },
b : { }
};
Using lodash how to get only [{ a: {} }] as result. Basically how to find an object inside list of objects using key.

Lodash has a _.get function.
documentation
The nice thing about _.get is that it'll protect you against TypeError exceptions.
In the example below, I am looking for the value of obj.a.b.c. The problem here is that there isn't a property c on obj.a.b object. This will throw a TypeError. With _.get, you can anticipate this and give it a default value if obj.a.b.c doesn't exist:
"use strict";
var _ = require('lodash');
var obj = {
a: {
b: 1
}
}
var value = _.get(obj, "a.b.c", "this is the default value");
console.log(value);
Output:
this is the default value

Related

All values getting upadted when tried to update single element in an associative array in Vue 3

I have the below code in Vue3:
data: function() {
return {
testData:[],
}
},
mounted() {
var testObj = {
name: 'aniket',
lastname: 'mahadik'
}
for (let index = 0; index < 3; index++) {
this.testData.push(testObj);
}
},
methods: {
updateLastName: function(key) {
this.testData[key].lastname = 'kirve';
}
}
When I call updateLastName(1) to update the lastname of only the second element, it's updating the lastname of all the elements.
I tried several ways but found no desired result.
Can someone point out to me what is going wrong here?
It is because you are pushing the reference to the same object in the array so when you update any item in the array you are instead updating every item since it reference the same object.
Either push by cloning the object :
testData.value.push({...testObj})
Or put the definition in the push
testData.value.push({ name: 'aniket', lastname: 'mahadik' })
Is JavaScript a pass-by-reference or pass-by-value language?

chai throw with property deep equal

expect.to.throw returns a Proxy to the thrown Error, so I can use with.property in order to check some properties of the error.
I attach a details object on my custom errors but I can't test for them, since the with.property compares only using strict equals.
Can I compare this property using deep equal somehow?
Example:
class DocNotFoundError extends Error {
constructor(message, docId) {
super(message)
this.details = { docId }
}
}
const getDoc = id => {
throw new DocNotFoundError('errors.docNotFound', id)
}
const docNotFound = expect(() => getDoc('01234567890')).to.throw('DocNotFoundError')
docNotFound.with.property('details', { docId: '01234567890' }) // fails
The error will fail similar to
AssertionError: expected { Object (error, ...) } to have property 'details' of { Object (docId) }, but got { Object (docId) }
+ expected - actual
I assume this is due to it only checks for reference equality and not deep object equality.
First of all there is a typo in the question: DocNotFoundError should not be in quotes.
I managed to get it working with docNotFound.to.have.deep.property('details', { docId: '01234567890' }), so yes you should perform deep comparison to check if objects have keys with same values.
Source 1
Source 2

Datatables mDataProp: val param undefined

I'm working on implementing a custom filter value where existing html tags are stripped away for each applicable table column values.
(The reason is that filtering the data also accounts for values inside the html tags, and this is not desired.)
This is a legacy code base, using datatables v1.9.0.
The table is constructed using params, such as aoColumns, aaData.
For table data is using array of arrays: i.e:
aaData = [
['12450','<a href='javascript:doStuff(123, 456)>value2</a>', 'User 1', '$500'],
['12455','...','...','...'],
['12462','...','...','...'],
['12314','...','...','...'],
[...],
...
]
Table has to use mDataProp for applicable aTargets
The function signature is:
tableOptions["aoColumnDefs"] = [
{
"mDataProp": function (source, type, val) {
console.log("source ", val); // This returns: row array
console.log("type ", type); // This returns each type (except for 'set')
console.log("val ", val); // This returns: undefined
var obj = {};
var temp = angular.element('div');
temp.innerHTML = val;
if (type === 'set') {
obj.value = val;
obj.value_filter = temp.textContent || temp.innerText;
console.log(obj.value_filter);
return;
} else if (type === 'filter') {
return val;
} else if (type === 'sort') {
return val;
}
return obj.value;
},
"sDefaultContent": '',
"aTargets": [ 1 ]
},
]
The issue is that val parameter inside mDataProp always returns undefined, so the table data population would error out, if not for the sDefaultContent property.
See this fiddle.
Why cannot the mDataProp get the val parameter populated? Does mDataProp support an array of arrays as data source? (The documentation is not clear about this)
After digging through a bit I found out that when mDataProp is used as a function, it does not have any reference to the data being passed to the datatable from the javascript array variable, thus returning undefined for val.
The workaround for this particular case is to use direct array position references in the source parameter, depending on the aTargets value to be used. (If using "aTargets": [ 1 ], then have to call source[1] in the mDataProp function).
I did not use if (type === "set"){}, 'cause I could not access it.
"mDataProp": function(source, type, val) {
var obj = {};
obj.value = source[1]; // Set column value
// Process value as desired ...
obj.value_filter = obj.value + ' foobar';
// Return value for filtering
if (type === 'filter') {
return obj.value_filter;
}
// Return original value for display, sort, etc.
return obj.value;
}
Click updated fiddle.

Watch for variable change do not work

I need to check variable rasters_previews_list for changing. Here is my code:
var userContent = Vue.extend({
template: '<p>Some template</p>',
data: function () {
return {
rasters_previews_list: []
}
},
watch: {
'rasters_previews_list': function(value, mutation) {
console.log("Value changed");
}
}
});
But In console I do not see Value changed when it got new data.
Data changing function:
map.on('draw:created', function (e) {
//...
Vue.http.post('/dbdata', DataBody).then((response) => {
userContent.rasters_previews_list = response; // putting JSON answer to Component data in userContent
console.log(response);
}, (response) => {
console.log("Can't get list rasters metadata from DB. Server error: ", response.status)
});
I change value in map.on('draw:created', function (e) (Leaflet JS). I see console.log output, so seems data is changing.
If you want to change the value of an array you will have to use the special Array extension methods Vue.set and Vue.delete.
Due to limitations of JavaScript, Vue cannot detect the following changes to an Array:
When you directly set an item with the index, e.g. vm.items[0] = {};
When you modify the length of the Array, e.g. vm.items.length = 0.
https://vuejs.org/api/#Vue-set
This problem is also mentioned in the common gotchas
When you modify an Array by directly setting an index (e.g. arr[0] = val) or modifying its length property. Similarly, Vue.js cannot pickup these changes. Always modify arrays by using an Array instance method, or replacing it entirely. Vue provides a convenience method arr.$set(index, value) which is just syntax sugar for arr.splice(index, 1, value).

get is not defined when trying to extends JSONSerializer

I try to define my custom serializer by extending DS.JSONSerialzer.
I pick the serialize function without modifications but when i run Ember,i get this error:
ReferenceError: get is not defined
This is my code :
import DS from 'ember-data';
export default DS.JSONSerializer.extend({
serialize: function(record, options) {
var json = {};
if (options && options.includeId) {
var id = get(record, 'id');
if (id) {
json[get(this, 'primaryKey')] = id;
}
}
record.eachAttribute(function(key, attribute) {
this.serializeAttribute(record, json, key, attribute);
}, this);
record.eachRelationship(function(key, relationship) {
if (relationship.kind === 'belongsTo') {
this.serializeBelongsTo(record, json, relationship);
} else if (relationship.kind === 'hasMany') {
this.serializeHasMany(record, json, relationship);
}
}, this);
return json;
},
});
I didn't change any code. This is the original. Why get is suddenly undefined? It's imported in line 1 in the original file JSONSerialiser
Can you help me?
They have get defined in the scope when creating the serializer, but that doesn't extend outside of their scope into your files.
var get = Ember.get;
var isNone = Ember.isNone;
var map = Ember.ArrayPolyfills.map;
var merge = Ember.merge;
Either replace all of the get methods with Ember.get or define get to be Ember.get