How do I get the value from this API? - javascript

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

Related

Accessing the first value of the first key in an object

I am having a little bit of an issue trying to get the value of a certain object. Since this is a bit hard to explain, I'll set up a scenario that follows what I need.
{"Gmail": {"example#example.com": "password1", "anotherexample#example.com": "password2}, ...}
I have an object (as represented above, we will call the object "encrypted"). I can get the value "Gmail" by using Object.keys(encrypted)[i] where i represents the index I'm looking for. The issue I am encountering is, how do I get exaxmple#example.com or password1?
I've been aimlessly wandering around it for a while trying to figure this out, searching for answers, but I can't seem to do so or find any that aren't based on arrays. Any help is great, thank you!
You could use Object.entries
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries
This turns objects into arrays of key - value which you can traverse, an example would be something like:
const data = {
"Gmail": { "example#example.com": "password1", "anotherexample#example.com": "password2" },
"Gmail2": { "example#example.com": "password1", "anotherexample#example.com": "password2" },
};
Object.entries(data).forEach(([key, value]) => {
const emailProvider = key;
const emailList = Object.entries(value);
console.log({ mail: emailProvider });
emailList.forEach(([email, password]) => {
console.log({ email, password })
})
});

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);
});

Access nested object JSON array with 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)
});

Difference between obj.key=value and obj.set(key, value)?

So while trying to update a document in mongoose, I realized that when I do obj.key=value to a document I obtained with Model.findOne(), it doesn'st assign the property to its value. But after trying obj.set(key, value), the property is assigned to its value in the document. So why is that? Usually when i do the first method to an object, the object gets the property. What is the .set() function? Does it have something to do with mongoose?
//this works
async function updateItem(){
let updatedItem = await Item.findOne({name:req.body.itemName});
Object.entries(req.body).forEach(elem=>{
if(elem[0]!=="itemName"){
updatedItem.set(elem[0], elem[1]);
};
});
};
updateItem();
});
//this doesn't work
async function updateItem(){
let updatedItem = await Item.findOne({name:req.body.itemName});
Object.entries(req.body).forEach(elem=>{
if(elem[0]!=="itemName"){
updatedItem.elem[0] = elem[1];
};
});
};
updateItem();
});
It means that updatedItem is not an object, it's a Map, and to add items to a Map you need to use the get method.
Another thing to point out is that when you set updatedItem.elem[0], you're literally trying to add the key "elem[0]" to updatedItem. To fix this, you need to use dynamic property notation with square brackets:
updatedItem[elem[0]] = elem[1];
This makes a new key with the value of elem[0], instead of the key being elem[0].

Get sum of property values from an observable array

I have an observable array and would like to get the sum of a property values in that array. My array is defined as:
public bookStores$: Observable;
I was going to do a simple for loop and calculate the sum, but I get a syntax error when trying to use the count property of my array:
Operator '<' cannot be applied to types 'number' and '<T>(this: Observable<T>, predicate?: (value: T, index: number, source: Observable<T>)=>boolean)...
This occurs when I do:
for (let i = 0; i < this.bookStores$.count; i++){ }
Every item in my array of BookStore objects has a property called numberOfBooks. What is the proper way to get the sum of those values contained on each BookStore object in my BookStore array?
This is why you're getting unexpected results for Observable.count
To get the array lenght of the results, you need to do, something like this:
BookStoreService.ts
...
getBookStore() : Observable<Bookstore> {
this.bookstore$ = this.http.get(...)
.map( (response:Response) => response.json() )
.map( response => response.bookstore); // optional depends if JSON payload you want is wrapped inside some other container
return this.bookstore$;
}
Component.ts
...
bookstore$ : Observable<Bookstore>;
bookstores: Bookstore[];
numberOfBookStores:number;
constructor(private bookService:BookService) {}
..
this.bookService.getJobs()
.subscribe(
bookstores => {this.bookstores = bookstores;
this.numberOfBookstores = this.bookstores.length;
},
err => { this.bookstores = [] as BookStore[];
// Caters for 404 etc error - be sure to be more robust in final code as you may want to indicate types of error back to user.
},
() => {
}
);
Update:
If you only need to loop through the list in yourHTML template, then
then defining the bookstores array as a property would not be necessary. I did this to illustrate how to get the size of the returned collection of bookstores.
You can use this type of syntax:
<tr *ngFor="let bookstore of (bookstore$ |async) as bookstores;
trackBy bookstore?.id; let i = index">
<td>{{bookstore.numberofBooks}}
<tr/>
You can find out more about:
*ngFor trackBy, even, odd, first, last here.
Using Async pipe for entire block of html template with AS here
Furthermore have a look at libraries like Lodash and Underscore for summing count of number of books. I've not used Underscore myself.
Here's a simple example to get you started.
If you want to get more adventurous have a look at this Functional Programming in Javascript Tutorial

Categories