Access nested object JSON array with Javascript - javascript

Using Logger.log(response.data.phone), I'm getting this in my log:
[{label=work, primary=true, value=5558675309}, {label=work, value=6108287680, primary=false}, {value=6105516373, label=work, primary=false}]
What I want is to return the two phone numbers as 5558675309, 6108287680.
I've tried Logger.log(response.data.phone.value) and that doesn't work. I've tried ...phone['value'], I've tried ...phone[0].value and this one does return the first phone number 5558675309. But I would like it to return all of the value values whenever I put in the phone key. So how would I modify the logger?

response.data.phone is an array you can try looping through it:
Logger.log(response.data.phone.map(phone => phone.value).join(', '));
const response = {data: {phone : [{label:'work', primary:true, value:5558675309}, {label:'work', value:6108287680, primary:false}, {value:6105516373, label:'work', primary:false}] } }
const Logger = { log : console.log};
Logger.log(response.data.phone.map(phone => phone.value).join(', '));

response.data is an array, response.data.phone does not exist. What you want is response.data[n].phone for an integer n. You can do this with a forEach loop.
response.data.forEach((element) => Logger.log(element.phone.value));
If for whatever reason you need support for older browsers you can use the older function syntax:
response.data.forEach(function(element){
Logger.log(element.phone.value)
});

Related

Selecting and adding values found with getElementsByClassName to dict or list

I am very new to JavaScript and I am trying to use it to select values from HTML using document.getElementsByClassName by putting index [0] from HTMLCollection. There is either one instance of the class being present or two or more.
const pizzatype = document.getElementsByClassName("pizzapizza")[0].innerHTML;
const pizzacheese = document.getElementsByClassName("cheesecheese")[0].innerHTML;
const pizzasauce = document.getElementsByClassName("saucesauce")[0].innerHTML;
const ordertotal = document.getElementsByClassName("fiyat")[0].innerHTML;
const order_dict = {
pizzatype,
pizzacheese,
pizzasauce,
ordertotal
}
const s = JSON.stringify(order_dict);
console.log(s); // returns {"pizzatype":"value1","pizzacheese":"value2","pizzasauce":"value3","ordertotal":"value4"}
The class is set like this:
<div class="cheesecheese card-text">${pizza.cheese}</div>
I tried experimenting with for loop, index(), .length, and others but I never got it to work. What would be the way to go to get return:
{
"pizzatype": "valuex1",
"pizzacheese": "valuex2",
"pizzasauce": "valuex3",
"ordertotal": "valuex4",
"pizzatype": "valuey1",
"pizzacheese": "valuey2",
"pizzasauce": "valuey3",
"ordertotal": "valuey4"
}
It should work even when there are more than 2 instances of those classes.
There is no way to store same key multiple times in Javascript object. You can use Entries syntax instead to get something similar.
Example of entries
[
[“pizzatype”, firstval],
[“pizzatype”, secondval],
]
Or you can use array of values inside your object.
To get result like so
{
pizzatype: [firstval,secondval],
…
}
You can get it with this way
{
pizzatype: Array.from(document.getElementsByClassName(“pizzapizza”)).map(elem => elem.innerHTML)
}

forEach not changing values of array

availableButtons.forEach(function(part, index) {
console.log(this[index].title)
// this[index].title = intl.formatMessage(this[index].title);
}, availableButtons)
The code above prints the console as follows:
{id: "abc.btn.xyz", defaultMessage: "someMessage"}
This confirms that each object has an id but when I try to execute the commented code it throws an error saying [#formatjs/intl] An id must be provided to format a message.
I used the same array but only a single object separately as follows intl.formatMessage(availableButtons[0].title); this gave me the required result I am just not able to figure out. I tried various ways of passing values in forEach, what am I missing?
forEach does not actually mutate arrays. it's just a shorthand loop called on the array. It's hard to suggest a solution because your intent is not clear.
availableButtons = availableButtons.map(button => {
//do your mutations here
}
might be a start
I think Array#map works better for in this vade
availableButtons.map(part => {
return {
...part,
title: intl.formatMessage(part.title)
};
});
Access the array (availableButtons) directly and update (mutate) with forEach.
availableButtons.forEach(function (part, index) {
console.log("before: ", availableButtons[index].title);
availableButtons[index].title = intl.formatMessage(this[index].title);
console.log("after: ", availableButtons[index].title);
});

How do I get the value from this API?

getCoinPrice(coinName: string) {
return this._http
.get(
`https://min-api.cryptocompare.com/data/pricemulti?fsyms=${coinName}&tsyms=EUR`
).pipe(map((result) => (result)));
JSON from the link with "BTC" as coinName is: {"BTC":{"EUR":8226.43}} and the method gives me back an observable.
How would I return the price value(8226.43) in a variable?
Try this code. Should just work fine for you.
getCoinPrice(coinName: string) {
return this._http
.get(
`https://min-api.cryptocompare.com/data/pricemulti?fsyms=${coinName}&tsyms=EUR`
).pipe(map((result) => (result.BTC.EUR)));
You can learn more about how to access objects and their value here https://www.w3schools.com/js/js_objects.asp
Here is the Javascript MDN explanation about how to work with objects: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects
Working example:
This is to show how we will get the value you desired by accessing the objects with .
//Your results
var result = JSON.parse('{"BTC":{"EUR":8226.43}}');
//This will print out 8226.43
console.log(result.BTC.EUR)
You want result[coinName]["EUR"]
As per observable result you are getting {"BTC":{"EUR":8226.43}} for coinName BTC, you want to retrieve "8226.43" from it.
So,
coinName = 'BTC' & observableResult = {"BTC":{"EUR":8226.43}}
If you want to get the value based on coinName, you could use the below method since coinName is also the key (BTC) in the observableResult object.
observableResult[coinName] // This will result to {EUR: 8226.43}
So, observableResult[coinName].EUR will result to 8226.43

Can I use .includes() to determines whether an array includes a certain element based on an array of strings instead of a single string?

Right now if I use this snippet of code, I get all elements whose region property is "Demacia"
let filtered = this.cards.filter((card) => {
return card.region.includes("Demacia");
})
Now I want to be able to get all elements whose property region is either "Noxus" or "Demacia", however, this doesn't seem to work as it returns an empty array
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return card.region.includes(regions);
})
Can I even do that or do I need to look into other array functions?
Instead of trying to pass multiple options to includes, look inside regions to see if it contains the region of the current card
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return regions.includes(card.region);
})
Just adding my answer because Array.prototype.includes() is not supported in IE, so if you want to support old browser, you can do
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes#Browser_compatibility
let regions = ["Demacia", "Noxus"];
let filtered = this.cards.filter((card) => {
return regions.indexOf(card.region) > -1;
})

ReactJS: Join map output with concatenating value

In my ReactJS application I am getting the mobile numbers as a string which I need to break and generate a link for them to be clickable on the mobile devices. But, instead I am getting [object Object], [object Object] as an output, whereas it should be xxxxx, xxxxx, ....
Also, I need to move this mobileNumbers function to a separate location where it can be accessed via multiple components.
For example: Currently this code is located in the Footer component and this code is also need on the Contact Us component.
...
function isEmpty(value) {
return ((value === undefined) || (value === null))
? ''
: value;
};
function mobileNumbers(value) {
const returning = [];
if(isEmpty(value))
{
var data = value.split(',');
data.map((number, index) => {
var trimed = number.trim();
returning.push(<NavLink to={`tel:${trimed}`} key={index}>{trimed}</NavLink>);
});
return returning.join(', ');
}
return '';
};
...
What am I doing wrong here?
Is there any way to create a separate file for the common constants / functions like this to be accessed when needed?
First question:
What am I doing wrong here?
The issue what you have is happening because of Array.prototype.join(). If creates a string at the end of the day. From the documentation:
The join() method creates and returns a new string by concatenating all of the elements in an array (or an array-like object), separated by commas or a specified separator string. If the array has only one item, then that item will be returned without using the separator.
Think about the following:
const navLinks = [{link:'randomlink'}, {link:'randomlink2'}];
console.log(navLinks.join(','))
If you would like to use concatenate with , then you can do similarly like this:
function mobileNumbers(value) {
if(isEmpty(value)) {
const data = value.split(',');
return data.map((number, index) => {
const trimed = number.trim();
return <NavLink to={`tel:${trimed}`} key={index}>{trimed}</NavLink>;
}).reduce((prev, curr) => [prev, ', ', curr]);
}
return [];
};
Then you need to use map() in JSX to make it work.
Second question:
Is there any way to create a separate file for the common constants / functions like this to be accessed when needed?
Usually what I do for constants is that I create in the src folder a file called Consts.js and put there as the following:
export default {
AppLogo: 'assets/logo_large.jpg',
AppTitle: 'Some app name',
RunFunction: function() { console.log(`I'm running`) }
}
Then simply import in a component when something is needed like:
import Consts from './Consts';
And using in render for example:
return <>
<h1>{Consts.AppTitle}</h1>
</>
Similarly you can call functions as well.
+1 suggestion:
Array.prototype.map() returns an array so you don't need to create one as you did earlier. From the documentation:
The map() method creates a new array populated with the results of calling a provided function on every element in the calling array.
I hope this helps!

Categories