can't convert undefined into an object - javascript

I am getting the error "Can't convert undefined to object on the line return hasOwnProperty(prop); and I simply cannot figure out where the problem lies. I can post more of the code if necessary.
getCardProperty : function (card, prop, def) {
if (typeof def === "undefined") {
def = null;
}
// json synckolab object
if (card.synckolab) {
if (card.hasOwnProperty(prop)) // TODO better check for undefined?
{
return hasOwnProperty(prop);
}
return null;
}

hasOwnProperty(prop) doesn't exist - you need to qualify it with an object name. Just change it to card.hasOwnProperty(prop).
You can simplify it further:
if (card.synckolab) {
return card.hasOwnProperty(prop) || null;
}
This will return true or null. Or you can simplify even further:
if (card.synckolab) {
return card.hasOwnProperty(prop);
}
This will return true or false.

Related

Check property exist in object or not in JavaScript?

I have one problem statement.
Implement a function propertyExists(obj, path) that takes in an object and a path (string) as arguments and returns ‘False’ if the property doesn’t exist on that object or is null, else returns the value of the property.
And here is solution.
function propertyExists(obj,path) {
// Write logic here
let result = obj.hasOwnProperty(path);
if(result)
{
return (obj.path);
}
else
{
return result;
}
}
Is this correct way of doing it?
Multiple issues:
the first name of the function should represent what it is doing,
Path as variable name is vague but propertyName as a variable is clear.
what you should do is either:
write function called, "getValue" it returns value if exist or null
function getValue(obj,propertyName) {
if(!obj) { // if object not exist
return null;
}
return obj[propertyName];
}
write function called, "propertyExists" should return true if exist else false.
function propertyExists(obj,propertyName) {
if(!obj) { // if object not exist
return false;
}
return obj.hasOwnProperty(propertyName);
}
function propertyExists(obj,path) {
// Write logic here
for(i in path){
if(obj.hasOwnProperty(path[i]) === true){
obj = obj[path[i]];
}else{
return false;
}
}
return obj;
}
object->obj,propertyname->path
function propertyExist(obj, path){
if (obj.hasOwnProperty(path)) return obj[path];
else return false;
};
Here, as far as I can understand, the objects could be nested also.
Let's take obj as {"a":{"b":"dadsa"}} and path as ab
Now, the the solution which you have posted will not work. Ideally, it should return dadsa, but it will return false.
Try the below code, it will work for nested objects also.
function propertyExists(obj,path) {
// Write logic here
var val=obj;
for(a of path){
val=val[a];
if(!val)
return false;
}
return val;
}
function propertyExists(obj,path) {
var val = obj;
for (a of path) {
val = val[a];
if (!val){
return false;
}
return val;
}

Why i am getting this warning 159:35 warning Expected to return a value at the end of arrow function array-callback-return?

i have this code, i am using find to verify if a element exist:
firstly i was using for like this
for (const file of files) {
if (data.name === proName ) {
exist = true
}
}
this code now i have to use filter, find, contains, map what is the best to solve this problem?
lists.find(data => {
if (
data.name === proName
) {
return data
}
})
but i am getting this warning
159:35 warning Expected to return a value at the end of arrow
function array-callback-return
what happend?
The function doesn't always return. I.e. the else path doesn't have a return in it.
Just do
lists.find(data => data.name === proName)
and it'll infer the data.name === proName as being returned from the lambda, or arrow, function you pass into find.
Otherwise you'll want something like
lists.find(data => {
if (data.name === proName) {
return data
} else {
return null;
});
But returning null isn't what find expects; it expects a boolean.

Object extensions in nodeJS

Is it possible to have object extensions in JavaScript? For example
Extensions.js
function any.isNullOrEmpty() {
if (this == null || this == "") {
return true
}
return false
}
app.js
var x = ""
console.log(x.isNullOrEmpty()) //should log true
is this possible? How do I do it?
You could add a method to the Object prototype, and use the valueOf method to get the value of the string:
...but, because null is a primitive that cannot have a method, the only way I can think of to get the target to be null would be to use call, apply or bind.
But you would never do this in production code, because modifying the prototype of built-in objects is discouraged.
'use strict' // important for the use of `call` and `null`
Object.prototype.isNullOrEmpty = function() { return this === null || this.valueOf() === '' }
const s = ''
console.log(s.isNullOrEmpty())
const t = null
console.log(Object.prototype.isNullOrEmpty.call(t))
You could use Object.prototype to extend this type of functionality in JavaScript.
Object.prototype.isNullOrEmpty = function() {
if (this == null || this == "") {
return true
}
return false
}
var x = "";
x.isNullOrEmpty(); // returns true
you need to add your custom method into prop type of object or array or everything u want to use your method on it.
but in your case you need to this like code below:
Object.prototype.isNullOrEmpty = function(){
if (this === null || this == "") {
return true
}
return false
}
let a = {a:'10'}
console.log(a.isNullOrEmpty())
function validateValue(value){
function isNullEmpty(){
return (value === void (0) || value == null)
}
return { isNullOrEmpty }
}
}

Object has-property-deep check in JavaScript

Let's say we have this JavaScript object:
var object = {
innerObject:{
deepObject:{
value:'Here am I'
}
}
};
How can we check if value property exists?
I can see only two ways:
First one:
if(object && object.innerObject && object.innerObject.deepObject && object.innerObject.deepObject.value) {
console.log('We found it!');
}
Second one:
if(object.hasOwnProperty('innerObject') && object.innerObject.hasOwnProperty('deepObject') && object.innerObject.deepObject.hasOwnProperty('value')) {
console.log('We found it too!');
}
But is there a way to do a deep check? Let's say, something like:
object['innerObject.deepObject.value']
or
object.hasOwnProperty('innerObject.deepObject.value')
There isn't a built-in way for this kind of check, but you can implement it easily. Create a function, pass a string representing the property path, split the path by ., and iterate over this path:
Object.prototype.hasOwnNestedProperty = function(propertyPath) {
if (!propertyPath)
return false;
var properties = propertyPath.split('.');
var obj = this;
for (var i = 0; i < properties.length; i++) {
var prop = properties[i];
if (!obj || !obj.hasOwnProperty(prop)) {
return false;
} else {
obj = obj[prop];
}
}
return true;
};
// Usage:
var obj = {
innerObject: {
deepObject: {
value: 'Here am I'
}
}
}
console.log(obj.hasOwnNestedProperty('innerObject.deepObject.value'));
You could make a recursive method to do this.
The method would iterate (recursively) on all 'object' properties of the object you pass in and return true as soon as it finds one that contains the property you pass in. If no object contains such property, it returns false.
var obj = {
innerObject: {
deepObject: {
value: 'Here am I'
}
}
};
function hasOwnDeepProperty(obj, prop) {
if (typeof obj === 'object' && obj !== null) { // only performs property checks on objects (taking care of the corner case for null as well)
if (obj.hasOwnProperty(prop)) { // if this object already contains the property, we are done
return true;
}
for (var p in obj) { // otherwise iterate on all the properties of this object.
if (obj.hasOwnProperty(p) && // and as soon as you find the property you are looking for, return true
hasOwnDeepProperty(obj[p], prop)) {
return true;
}
}
}
return false;
}
console.log(hasOwnDeepProperty(obj, 'value')); // true
console.log(hasOwnDeepProperty(obj, 'another')); // false
Alternative recursive function:
Loops over all object keys. For any key it checks if it is an object, and if so, calls itself recursively.
Otherwise, it returns an array with true, false, false for any key with the name propName.
The .reduce then rolls up the array through an or statement.
function deepCheck(obj,propName) {
if obj.hasOwnProperty(propName) { // Performance improvement (thanks to #nem's solution)
return true;
}
return Object.keys(obj) // Turns keys of object into array of strings
.map(prop => { // Loop over the array
if (typeof obj[prop] == 'object') { // If property is object,
return deepCheck(obj[prop],propName); // call recursively
} else {
return (prop == propName); // Return true or false
}
}) // The result is an array like [false, false, true, false]
.reduce(function(previousValue, currentValue, index, array) {
return previousValue || currentValue;
} // Do an 'or', or comparison of everything in the array.
// It returns true if at least one value is true.
)
}
deepCheck(object,'value'); // === true
PS: nem035's answer showed how it could be more performant: his solution breaks off at the first found 'value.'
My approach would be using try/catch blocks. Because I don't like to pass deep property paths in strings. I'm a lazy guy who likes autocompletion :)
JavaScript objects are evaluated on runtime. So if you return your object statement in a callback function, that statement is not going to be evaluated until callback function is invoked.
So this function just wraps the callback function inside a try catch statement. If it catches the exception returns false.
var obj = {
innerObject: {
deepObject: {
value: 'Here am I'
}
}
};
const validate = (cb) => {
try {
return cb();
} catch (e) {
return false;
}
}
if (validate(() => obj.innerObject.deepObject.value)) {
// Is going to work
}
if (validate(() => obj.x.y.z)) {
// Is not going to work
}
When it comes to performance, it's hard to say which approach is better.
On my tests if the object properties exist and the statement is successful I noticed using try/catch can be 2x 3x times faster than splitting string to keys and checking if keys exist in the object.
But if the property doesn't exist at some point, prototype approach returns the result almost 7x times faster.
See the test yourself: https://jsfiddle.net/yatki/382qoy13/2/
You can also check the library I wrote here: https://github.com/yatki/try-to-validate
I use try-catch:
var object = {
innerObject:{
deepObject:{
value:'Here am I'
}
}
};
var object2 = {
a: 10
}
let exist = false, exist2 = false;
try {
exist = !!object.innerObject.deepObject.value
exist2 = !!object2.innerObject.deepObject.value
}
catch(e) {
}
console.log(exist);
console.log(exist2);
Try this nice and easy solution:
public hasOwnDeepProperty(obj, path)
{
for (var i = 0, path = path.split('.'), len = path.length; i < len; i++)
{
obj = obj[path[i]];
if (!obj) return false;
};
return true;
}
In case you are writing JavaScript for Node.js, then there is an assert module with a 'deepEqual' method:
const assert = require('assert');
assert.deepEqual(testedObject, {
innerObject:{
deepObject:{
value:'Here am I'
}
}
});
I have created a very simple function for this using the recursive and happy flow coding strategy. It is also nice to add it to the Object.prototype (with enumerate:false!!) in order to have it available for all objects.
function objectHasOwnNestedProperty(obj, keys)
{
if (!obj || typeof obj !== 'object')
{
return false;
}
if(typeof keys === 'string')
{
keys = keys.split('.');
}
if(!Array.isArray(keys))
{
return false;
}
if(keys.length == 0)
{
return Object.keys(obj).length > 0;
}
var first_key = keys.shift();
if(!obj.hasOwnProperty(first_key))
{
return false;
}
if(keys.length == 0)
{
return true;
}
return objectHasOwnNestedProperty(obj[first_key],keys);
}
Object.defineProperty(Object.prototype, 'hasOwnNestedProperty',
{
value: function () { return objectHasOwnNestedProperty(this, ...arguments); },
enumerable: false
});

In Javascript, how can I check the existence of a specific key/value pair nested inside another key/value pair?

For example, this is the value of the object I am processing:
object = {"message":"success","dataList":{"state":"error","count":"25"}}
I know that to check if key "message" exists, I can do the following:
if(object['message']){
//"message" exists. do stuff.
} else{
//"message" does not exist
}
How do I check for the existence of "state" or "count" though?
if(object['dataList']['state']){
// dataList["state"] exists. do stuff.
} else {
// dataList["state"] does not exist
}
or the (in my opinion) more readable:
if(object.dataList.state){ ... }
Edit: It would also be a good idea to check for all parent objects so you will not get an unexpected error when, for example, dataList does not exist on the object:
if (object && object.dataList && object.dataList.state)
try like this:
object = {"message":"success","dataList":{"state":"error","count":"25"}};
if(object.message =='success'){
console.log(object.dataList);// your datalist object here use it
console.log(object.dataList.state);
console.log(object.dataList.count);
} else{
//"message" does not exist
}
if you are trying to check state do this:
if(typeof(object.dataList.state) !='undefined' && object.dataList.state.length > 0){
// dataList.state exists. do stuff.
} else {
// dataList.state does not exist
}
if (object.dataList.state || object.dataList.count) {
// ...
}
First of all, if you are checking the existence of a property, you should use if ('message' in object). If you use if (object['message']), for the case object = {'message': null}, the result is wrong.
In your question, the object is nested into two layers. If there are more than two, you can try a generic solution using recursion:
function findProperty (obj, key) {
if (typeof obj === "object") {
if (key in obj) return true;
var childReturned = false;
for (k in obj) {
childReturned = findProperty(obj[k], key);
if (childReturned) return true;
}
}
return false;
}
var obj = {"message":"success","dataList":{"state":"error","count":"25"}};
findProperty(obj, 'message'); // => true
findProperty(obj, 'dataList'); // => true
findProperty(obj, 'state'); // => true
findProperty(obj, 'count'); // => true

Categories

Resources