Grab an object out of objects base on specific field value - javascript

In my AngularJS
this.device return 15 objects. Each object contain a dataType field and it has diff values on all 15 of them. I would like to grab/access only if dataType == "PROTOCOL" I would do something like this if I have access to underscore.js, but in this project, I don't have it.
this.device.protocol = _.find(this.device, {dataType: "PROTOCOL"});
What is JS way to access this without having to do a for-loop?

You can use Array#find.
The find() method returns the value of the first element in the provided array that satisfies the provided testing function. If no values satisfy the testing function, undefined is returned.
this.device.protocol = this.device.find(x => x.dataType === "PROTOCOL");

You can use Array.filter and check against your desired property.
this.device.protocol = this.device.filter(({dataType}) => dataType == "PROTOCOL")[0];

Related

Validate if object has string

I have this array
switched = {"Restaurant":1,"Hotel":2,"Beauty shop":3,"Physiotherapist":4,"Dentist":5,"Bar":6,"Coffee shop":7}
and this object
result = [{"Google Place URL":"http://www.restaurant.com","Business Type":"Restaurant"},{"Google Place URL":"http://www.hotel.com","Business Type":"Hotel"}]
I want to validate if every item of the result contains words of switched
also, I'm already working with a for that returns each item separately
item[csvBusinessType] = Restaurant
how can I validate if item[csvBusinessType] is included in switched?
I have tried with
let n = switched.includes(item[csvBusinessType]);
but I get Uncaught TypeError: switched.includes is not a function
There is not good native method for this. Better to use lodash library https://www.npmjs.com/package/lodash
Here is an example
const _ = require('lodash');
console.log( _.includes(switched, item[csvBusinessType]));
I converted the object to string and used includes, I don't know if it will be the best way, but I think it is the most supported by browsers
let businessListArray = JSON.stringify(switched);
let checkBusiness = businessListArray.includes(item[csvBusinessType]);
I want to validate if every item of the result contains words of switched
If you want to validate that every item of the result object array contains words of the switched array, you should look into JS Array methods and working with Objects, just as #Andreas suggested.
In this specific case, your switched object has keys that appear to match the csvBusinessType of your item objects. This is helpful as we can use Object.keys() to grab all the keys of your switched object as an array of strings.
const businessTypes = Object.keys(switched) // = ["Restaurant","Hotel","Beauty shop","Physiotherapist","Dentist","Bar","Coffee shop"]
Now that we have grabbed the keys that you want to check against, we can use the JS Array method every() to perform a test against every object in your result object array. In this case, we will be testing that the obect's Business Type is included in our newly created businessTypes array.
const resultsValid = result.every((resultObject) => businessTypes.includes(resultObject["Business Type"]));
resultsValid is a boolean that is true if all objects in result had a Business type that matched one of the keys of your switched object.
NOTE: You may want to check Letter Casing before some of these comparisons unless you want to explicitly match only exact matches ("Beauty shop" will NOT match "Beauty Shop" for example).

iteration of a JSON containg objects

I am trying to write a function that takes pokemon’s name as an argument and find out which all pokemon have that name in their “next_evolution” field
Consider the following JSON dataset -
visit https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json
now for that, I've written the following function:
var infoOfPokemon = function(nameOfPokemon,allPokemon){
for(x in allPokemon){
if(allPokemon[x].next_evolution.includes(nameOfPokemon)){
console.log('pokemons found: '+allPokemon[x].name)
} else{
null
}
}
}
var nameOfPokemon =prompt('enter the name of Pokemon')
infoOfPokemon(nameOfPokemon,pokemonData.pokemon)
but it is returning an error which says
Uncaught TypeError: Cannot read property 'includes' nextEvolution.js:4090 of undefined
One or more of your pokemon does not have a 'next_evolution' field set (for example, the one with id 3 in your file). Hence allPokemon[x].next_evolution evaluates to undefined and you cannot read 'includes' on that.
Check for the existence of next_evolution, first.
if (allPokemon[x].next_evolution &&
allPokemon[x].next_evolution.includes(nameOfPokemon)) { ...
and find out which all pokemon have that name in their “next_evolution” field
That should make you think of filter. You want to filter the list of pokemon to find the matching ones.
But, as already pointed out, you need to be able to return false in your filter predicate if the pokemon you're testing does not have a next_evolution field. You can do that via testing, as suggested in another answer: pokemon.next_evolution && pokemon.next_evolution.includes..., or you can default it, as below: (pokemon.next_evolution || []).includes...
(Note though that both you original and that answer miss a step, which is to then collect that name properties from those next_evolution values.
So here is a simple function which should filter the list to find the correct items. To use it with a call to your API, I wrap it in a fetch call, and simply console.log the results. Obviously, you might well have other ways to call it.
const infoOfPokemon = (name, all) => all.filter(pokemon =>
(pokemon.next_evolution || []).map(p => p.name).includes(name)
)
fetch('https://raw.githubusercontent.com/Biuni/PokemonGO-Pokedex/master/pokedex.json')
.then(resp => resp.json())
.then(allPokemon => console.log(
infoOfPokemon('Butterfree', allPokemon.pokemon) //~> [{Caterpie}, {Metpod}]
))
You cannot use includes function directly on array having objects instead of single object. It will give false as output.
For e.g:
var pets = [{'name':'cat'},{'name':'dog'},{'name':'bat'}];
console.log(pets.includes("cat")) //false
This results in false always.
Proper way is to use a map to get a particular object field on which you want to use includes function.
e.g:
var pets = [{'name':'cat'},{'name':'dog'},{'name':'bat'}];
console.log(pets.map((obj)=> obj.name).includes("cat")); //true
In Your case first see if allPokemon[x].next_evolution is undefined or not (i.e next_evolution key is present or not)
code becomes:
if (allPokemon[x].next_evolution &&
allPokemon[x].next_evolution.(obj)=> obj.name).includes(nameOfPokemon)) { ...

Javascript apply .join() to item in object collection only if not undefined/empty/null?

In Javascript I have a collection of objects, whose values I'm storing in variable
var filters = {
BeginDate: $("#BeginDateRange").val(),
EndDate: $("#EndDateRange").val(),
ListOfCodes: $("#ListOfCodes").val(),
//ListOfCodes: $("#ListOfCodes").val().join(),
...
}
Based on where I use the collection, some of its objects remain 'undefined', and it is intended.
ListOfCodes above is an array of string values, and I want to pass it to the binder as a single comma-separated string (e.g ["1"], ["2"] -> "1,2")
I was able to make a use of .join(), and it worked successfully. However, I found later that the code will crash if the .join() does not have a value to join.
Is there a way to apply .join() INSIDE the collection to the variable ONLY if it has value? Something like
var filters = {
BeginDate: $("#BeginDateRange").val(),
EndDate: $("#EndDateRange").val(),
ListOfCodes: if( $("#ListOfCodes").val() )
{$("#ListOfCodes").val().join()}
else
{$("#ListOfCodes").val()} //value remains undefined
,
...
}
EDIT: I ask about the possibility of applying .join() method inside the collection, not checking for empty values.
Just moving this as an answer.
What about a ternary statement?
ListOfCodes: ($("#ListOfCodes").val()) ? $("#ListOfCodes").val().join() : null

find value in complex object javascript

Basically I have a complex object that retrieves the GPT API (google publisher tag) with this function:
googletag.pubads().getSlots();
The object value is something like this:
I need to know if there is a way to compare the value of each property with an X value without getting a problem of recursivity (because the object is huge and i need to to that validation several times)
Also, I tried to convert that object into a JSON with JSON.stringify(), and then tried to get the value with a regex, faster, but with this option, I have the problem with Cyclic Object Value.
Any suggestions ?
it's more simple. try it to convert it into an array and later use a filter for comparative with your value.
var objGoogle = {};
var arrayObjectGoogle = [objGoogle];
var filter = arrayObjectGoogle.filter(function(obj){
obj.yourAttr == yourValue; });
this will give you a second array with the values found it. later, index the array for pick up the value do you need.

Safe way to check if array element exists?

I have a 2D array.
I currently access that array using notation such as:
myArray[5][9] (for example).
What is the safest way to check whether or not a certain array element exists?
For example, let's say I am looping through the array and retrieving a property of each array element like so:
myArray[5][9].firstName
I then come to myArray[9][11].firstName (for example) which doesn't exist. Clearly this will throw an exception as the element doesn't exist.
How can I deal with this? I'm not looping through the entire array (i'm accessing it's contents randomly and say using myArray.lengthin a for loop will not work.
Is there a JS function / method for checking whether or not an array element exists?
Thanks.
Safe call operator ?. looks fine. Warning: many, but not all implementations (and versions) of JavaScript supports it.
For your example it will looks like
myArray[5][9]?.firstName
EDIT: Thanks to Asaf's comment there is safer version
myArray?.[5]?.[9]?.firstName
like
if (!('firstname' in myArray[i][j])) { ... }
Just check it with if condition.
if(myArray[i][j].firstName){
}
You can use the hasOwnProperty method to check if an array item exists:
if (myArray.hasOwnProperty(x) && myArray[x].hasOwnProperty(y)) {
var name = myArray[x][y].firstName;
}
This checks both dimensions. If you know that the first index (x in the example) is always inside the range, you can skip the first test.
If you store some other values in the array also, you would need to check if the item has the firstName property:
if (myArray.hasOwnProperty(x) && myArray[x].hasOwnProperty(y) && myArray[x][y].hasOwnProperty('firstName')) {
var name = myArray[x][y].firstName;
}

Categories

Resources