Filter API response directly in URL - javascript

I would like to know if it is possible to filter the response of an API directly via the URL.
URL API : https://coronavirus-19-api.herokuapp.com/countries
I only put 2 countries for the example but the structure of the answer is like this:
[
{
"country":"USA",
"cases":176518,
"todayCases":12730,
"deaths":3431,
"todayDeaths":290,
"recovered":6241,
"active":166846,
"critical":3893,
"casesPerOneMillion":533,
"deathsPerOneMillion":10,
"firstCase":"\nJan 20 "
},
{
"country":"Italy",
"cases":105792,
"todayCases":4053,
"deaths":12428,
"todayDeaths":837,
"recovered":15729,
"active":77635,
"critical":4023,
"casesPerOneMillion":1750,
"deathsPerOneMillion":206,
"firstCase":"\nJan 29 "
}
]
For the moment in my project I collect all the responses and I filter afterwards to have only the data for a country but to optimize performance I would like to filter the responses directly by URL.
async getCountryStats() {
try {
let response = await fetch("https://coronavirus-19-api.herokuapp.com/countries")
if (response.status === 200) {
let data = await response.json()
// Data object with ID
data = Object.assign({}, data)
// Data object with name of property
let obj = {}
for (let i in data) {
obj = { ...obj, [data[i].country]: data[i] }
}
this.setState({ focusStats: obj[this.state.focusCountry] })
} else {
this.setState({ errorStatus: true })
console.error('Error status')
}
} catch (err) {
console.error(err)
}
}
I use React, here is my repository: https://github.com/michaelbaud/covid19, here is the rendering: https://suspicious-kilby-d90f99.netlify.com

You can use the following link instead:
https://coronavirus-19-api.herokuapp.com/countries/{country-name}
For example in your case it would be:
USA : https://coronavirus-19-api.herokuapp.com/countries/USA
Italy : https://coronavirus-19-api.herokuapp.com/countries/italy
Good Luck

Related

Express JS unlimited query parameter function?

I'm trying to set an unlimited query parameter in express js.But I couldn't figure out how should I implement that in my code. I'm using MongoDB aggeration
I want to build unlimited facets searched with multiple $match stage
Which works like this:
'http://localhost:4000/search?text=mango'
'http://localhost:4000/search?text=mango&key=brand&value=rasna' //unlimited facets.
'http://localhost:4000/search?text=mango&key=brand&value=rasna&key=color&value=yellow' //unlimited facet parameters
Here's my code to do this:
app.get("/search", async(request, response) => {
try {
const textsearch = request.query.text;
var keystore = request.query.key; //storing `key` in 'keystore'
var valuestore = request.query.value; //storing `value` in `valuestore`
if (keystore, valuestore) {
facetjson = [
{
'$match': {
[keystore]: `${valuestore}` //Storing key and value in $match
}
}
]
const Pipeline = [{
'$search': {
'text': {
'query': `${textsearch}`,
'path': 'title',
}
}
},
{
'$limit': 5
}
]
//Pushing 'facetjson' array into Pipeline array to make a filtered search possible.
const newitem = insert(Pipeline, Pipeline.length - 1, facetjson)
let result = collection.aggregate(newitem).toArray();
response.send(result);
} else {
const Pipeline = [{
'$search': {
'text': {
'query': `${textsearch}`,
'path': 'title',
}
}
},
{
'$limit': 5
}
]
let result = collection.aggregate(Pipeline).toArray();
response.send(result);
};
} catch (error) {
response.status(500).send({ message: error.message });
}
})
(JSFIDDLE code Example)[https://jsfiddle.net/divyanshuking/z0vo589e/]
==> I know that I've to pass $match in the Pipeline array each time for single Key , Value Pair. Doing many google searches I've figured out that I've to use the Rest Parameter (...keystore,...valuestore). But I didn't know how to implement this. Have you guys any better idea to do solve this problem? Pls help me:
Why don’t you use forEach or something
function endPoint (req, res) {
const queriesFound ={}
req.query.forEach(query=>{
queriesFound[query]=query;
}
QueriesFound will be an object
{ “Name”:”Name”, “AnotherParam”:”AnotherParam” }
}
//QueriesFound will be an object
{
“Name”:”Name”,
“AnotherParam”:”AnotherParam”
}
Your request URL has a wrong structure for query parameters. If you want to pass multiple kay/value pairs in URL, the correct structure is like this:
'http://localhost:4000/search?text=mango&brand=rasana&color=yellow
This code should work with this URL structure:
app.get("/search", async(request, response) => {
try {
//We need "search pipeline stage" in all conditions. whether we got a key/value pair in query or not.
//so we use "search stage" when declare pipeline array;
let pipeline = [{
'$search': {
'text': {
'query': `${request.query.text}`,
'path': 'title',
}
}
}];
//If there are keys/values pairs in the query parameters, we add match stage to our pipeline array;
if(request.query) {
let match = {}, hasMatchSatge = false;
for(let item in request.query){
if(item !=== 'text'){
match[item] = request.query[item];
hasMatchStage = true;
}
}
if(hasMatchStage) pipeline.push({'$match': match});
}
//Finally, we add our "limit stage" to the pipeline array;
pipeline.push({'$limit' : 5});
let result = collection.aggregate(pipeline).toArray();
response.status(200).send(result);
} catch (error) {
response.status(500).send({ message: error.message });
}
})

map method not working at some place using javascript / node js

I have Output in JSON format and i want to specific field from it
{
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
}
I am using map function to get the value but the problem is i can only fetch the value of id and name not Data.id and Data.path
so i am getting this value from my database and this is my code by how i am getting the value from database
function runRest(req, res) {
let data = req.body;
Owner.findAll({
raw: true,
where: {
id: data.id,
},
include: {
model: kingdom,
required: false,
},
attributes: ["id", "name"],
})
.then((parents) => {
parents.map((value) => {
console.log(value);
});
})
.catch(function (err) {
console.log(err);
});
}
let value={
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
};
value.map((data)=>{
console.log(data.id);
});
I can only fetch data which is in white font color which is ID and name any solution how can i get Data.id and Data.path by using map function
I even tried this
let links = value
.map((child) => {
for (let i in child)
if (i === "Data.id") {
return child[i];
}
})
but i don't want to use this for method any chance I can use Map function ?
The object
values = {
"id":"01",
"name":"fish",
"Data.id":"f01",
"Data.path":"/home/work/fish.jpg"
};
Has the keys: "id", "name", "Data.id", "Data.path"
To get the value "f01" you must use the key "Data.id":
foo = values["Data.id"]; // foo === "f01"
In the comments you mention that you want to map an array of these objects to the data id:
idArray = objects.map(value => value["Data.id"]);

Unable to get information from Array

```
function displayResults(responseJson) {
const gamedata = responseJson.results.map(game => {
return {
name: game.name,
consoles: game.platforms,
metacritc: game.metacritic,
genre: game.genres
};
});
console.log(gamedata);
inputData(gamedata);
}
function platformdata(consoles) {
return consoles.map(system => {
return system.platform.name;
});
}
function inputData(gamedata) {
gamedata.map(input => {
$(`#home-list`).html(`
<h1>${input.name}</h1>
<h5>${input.metacritc}</h5>
<span>${input.system}</span>
`);
});
}
```
I have been trying to get information from an array but have not been successful in obtaining the information. The information for the game platforms is somewhat nested and I have been trying to dig it out but to no avail.
https://api.rawg.io/api/games?page_size=1
Best way I can show the information more in detail is to just advise to throw the link above into postman and you'll see what I am trying to work with. Basically it is under results > platforms > platform > name. When I add this information into the map function it comes up undefined. Running it now they come up with saying object with commas. I'd like it to just come up with just the information leaving out the commas. I can't figure out how to get join() to go into html(). Thank you very much!
Edit:
1) Results I'd like is to be able to pull up is within the platforms tree but is buried. If I just use game.platforms it produces [object, Object]. If I try to add more to the line in gamedata it will produce undefined.
2) In "gamedata.map(input => {" ?
3) Yes I tried making a helper function based on code I found online. The code I found online used excessive li and ul
```
function platformnames(platforms) {
return platforms.map(system => {
return '<li>' system.platform.name + '</li>';
});
}
function pullArray(gamedata) {
gamedata.map(function(input) {
let platformNames = input.platforms.map(
system => `<li>${system.platform.name}</li>`
);
$(`#home-container`)
.append(`<li><ul><li>${platformNames}</li></ul></li>`)
.join(' ');
});
}
```
This worked but gave really odd results.
4) No I'm adding it all to the same ID as one pull.
5) That is me trying to mine the information from platforms on an API. It's buried in there and I haven't found a good solution.
function formatParams(params) {
const queryItems = Object.keys(params).map(
key => `${key}=${params[key]}`
);
console.log(queryItems);
return queryItems.join('&');
}
const opts = {
headers: {
'User-Agent': `<ClassProject> / <VER 0.01> <Currently in Alpha testing>`
}
};
function fetchAPI() {
const params = {
...($('.search-param').val() && {
search: $('.search-param').val()
}),
...($('.genre-param').val() && {
genres: $('.genre-param').val()
}),
...($('.platforms-param').val() && {
platforms: $('.platforms-param').val()
}),
...($('.publishers-param').val() && {
publishers: $('.publishers-param').val()
}),
page_size: '1'
};
console.log(params);
const baseURL = 'https://api.rawg.io/api/games';
const queryString = formatParams(params);
let url = `${baseURL}?${queryString}`;
console.log(url);
fetch(`${url}`, opts)
.then(response => response.json())
.then(responseJson => displayResults(responseJson))
.catch(error => {
console.log(`Something went wrong: ${error.message}`);
});
}
function displayResults(responseJson) {
const gamedata = responseJson.results.map(game => {
return {
name: game.name,
consoles: game.platforms,
metacritc: game.metacritic,
genre: game.genres
};
});
console.log(gamedata);
inputData(gamedata);
}
function inputData(gamedata) {
let html = '';
gamedata.forEach(input => {
html += `<h1>${input.name}</h1>`;
html += `<h5>Metacritic: ${input.metacritic ||
'No metacritic rating'}</h5>`;
html += 'Platforms:<br />';
input.consoles.forEach(e => {
html += `<span>${e.platform.name}</span><br />`;
});
html += `<br /><span>System: ${input.system}</span>`;
});
document.getElementById('home-list').innerHTML = html;
}
function pageLoad() {
$(document).ready(function() {
fetchAPI();
});
}
pageLoad();
So I'm close thanks to the help of everyone here. Now I'm returning "Metacritic: No metacritic rating" or if I remove that or part an undefined. What am I missing?
The snippet below gets you the platform names. I modified/created
the displayResults() function to only return a value (and also corrected the typo in metacritic (metacritc -> metacritic))
the inputData() function to create a correct HTML and append it to the container
a fetchData() function to actually fetch the data
an unnamed function to initiate fetch and display the data
You should look at your data - you don't use game.genres (although you map it) and you would like to display input.system that is not mapped.
function displayResults(responseJson) {
return responseJson.results.map(game => {
return {
name: game.name,
consoles: game.platforms,
metacritic: game.metacritic,
genre: game.genres
};
});
}
function platformdata(consoles) {
return consoles.map(system => {
return system.platform.name;
});
}
function inputData(gamedata) {
let html = ''
gamedata.forEach(input => {
html += `<h1>${input.name}</h1>`
html += `<h5>Metacritic: ${input.metacritic || 'No metacritic rating'}</h5>`
html += 'Platforms:<br />'
input.consoles.forEach(e => {
html += `<span>${e.platform.name}</span><br />`
})
html += `<br /><span>System: ${input.system}</span>`
});
document.getElementById('home-list').innerHTML = html
}
async function fetchData() {
const data = await fetch('https://api.rawg.io/api/games?page_size=5')
const json = await data.json()
return json
}
(async function() {
const json = await fetchData()
inputData(displayResults(json))
})();
<div id="home-list"></div>
And although it does work - you're not supposed to use more than one h1 tag on a site - it will be an HTML validation warning (SEO!). If you will display only one game per page, then forget my remark :)

Get Data from parsed XML to JSON

I'm trying to get some data from a parsed XML to JSON but now I'm stuck and not be able to get the data. Could someone show me how to get the data in the right way to show on my screen?
Formatted JSON Data
{
"event":[
{
"name":"Queen",
"date":"2019-09-12",
"genre":"rock",
"time":"20:00:00",
},
{
"name":"2Pac",
"date":"2019-09-25",
"genre":"rap",
"time":"20:00:00"
},
data () {
return {
result: null
}
},
created () {
this.getConcertData()
},
methods: {
getConcertData () {
const parseString = require('xml2js').parseString
this.$axios.get('members.php?xml')
.then((response) => {
const self = this
parseString(response.data, function (err, result) {
self.events = result
console.log(result)
})
})
}
}
You can try to confirm if you have successfully obtained the expected format data(use developer tools or just log the response.data),
then make sure require('xml2js').parseString work well.

After subscribe save value into array or variable

I want to save the data after http request and subscribing like below but I cant see the data at the first index. It looks like this within the browser. With this.mySet[0] I have not access to this. What it wrong?
[]0: "test"length: 1__proto__: Array(0)
api.service.ts:409
myComponent.ts
mySet = [];
getLageSub() {
this.apiService.getLage().subscribe(data => {this.mySet.push(data)});
console.log(this.mySet)<------here is my output but I will need it elsewhere
}
myService.ts
getLage() {
let url = 'rest/getData-pool';
try {
return this.http.post(url, {}, this.getPutHeaders()).map((res) =>res.json())
} catch (error) {
console.log(error);
}
}
I hope it will help:
mySet : any;Constructor(){this.mySet = [];}
getLageSub() { this.apiService.getLage().subscribe(data => {this.mySet.push(JSON.parse(JSON.stringify(data)))}); console.log(this.mySet)<------here is my output but I will need it elsewhere }
Try this case :
mySet : any;Constructor(){this.mySet = [];}
getLageSub() { this.apiService.getLage().subscribe(data => {this.mySet.push(data)}); console.log(this.mySet)<------here is my output but I will need it elsewhere }

Categories

Resources