How to reach multiple elements in an array without using axios - javascript

Yesterday i saw a React project on youtube and i wanted to test it myself.
This function connects to the link and returns me the questions of the category and difficulty I selected with my buttons . code works fine ,but i don't want to do that step with axios and any API related stuff.
const fetchQuestions = async (category = "", difficulty = "") => {
const { data } = await axios.get(
`https://opentdb.com/api.php?amount=10${
category && `&category=${category}`
}${difficulty && `&difficulty=${difficulty}`}&type=multiple`
);
console.log(category);
console.log(difficulty);
setQuestions(data.results);};
I only want to see the questions in the difficulty and category I chose .
So i created a json file and tried to get those questions&answers etc. with that but it didn't work . I tried to map things inside and log category and difficulty but i can't even reach those . I know that i need some conditions etc. but i can't create the logic .
const fetchQuestions =(category="",difficulty="")=>{const {data}=QuestionList.results.map((q)=> (console.log(category),console.log(q[category]),console.log(data),console.log(q[difficulty]))); setQuestions(data.results);}
this is json file : questions.json -> i imported as QuestionList
{
"response_code": 0,
"results": [
{
"category": "Books",
"type": "multiple",
"difficulty": "medium",
"question": "some question?",
"correct_answer": "blabla",
"incorrect_answers": ["Transformers", "Care Bears", "Rubik’s Cube"]
},
{
"category": "Books",
"type": "multiple",
"difficulty": "easy",
"question": "sdklgksdflgjsdf",
"correct_answer": "Badminton",
"incorrect_answers": ["Table Tennis", "Rugby", "Cricket"]
},
{
"category": "Books",
"type": "multiple",
"difficulty": "medium",
"question": "fgdfgdfgdfgdfgg?",
"correct_answer": "9",
"incorrect_answers": ["6", "10", "3"]
},
{
"category": "Films",
"type": "multiple",
"difficulty": "medium",
"question": "asdasdasdasd",
"correct_answer": "Parlor",
"incorrect_answers": ["Open Room", "Sitting Room", "Loft"]
},
{
"category": "Films",
"type": "multiple",
"difficulty": "medium",
"question": "asdasdasddddd",
"correct_answer": "Link",
"incorrect_answers": ["Wario", "Q*bert", "Solid Snake"]
}
]}
I've been stuck on this for 9 hours but i still have no solution :)

Issue
const fetchQuestions = (category = "", difficulty = "") => {
const { data } = QuestionList.results.map(
(q) => (
console.log(category),
console.log(q[category]),
console.log(data),
console.log(q[difficulty])
)
);
setQuestions(data.results);
};
The code above is calling the Array.prototype.map function but the callback is returning a Comma Operator expression and the last operand's return value is what is returned. console..log is a void return, however, so undefined is returned as the map value. On top of the, .map returns an array, not an object, so there's no data property to destructure from the mapped array. Later accessing data.results is likely throwing a TypeError, something to effect of "cannot access 'results' of undefined".
Solution
If I understand your question correctly you have just created a local questionList JSON file that is imported and you are wanting to filter the results by some search criteria.
Example:
const [questions, setQuestions] = useState([]);
const fetchQuestions = (category = "", difficulty = "") => {
const data = questionList.results.filter(
(question) =>
question.category.toLowerCase().includes(category.toLowerCase()) &&
question.difficulty.toLowerCase().includes(difficulty.toLowerCase())
);
setQuestions(data);
};
useEffect(() => {
fetchQuestions();
}, []);
fetchQuestions(); - returns all 5 results
fetchQuestions("books"); - returns the 3 "books" category entries
fetchQuestions("", "easy"); - returns the 1 "easy" difficulty entry

Related

How can you render the objects of a list that contains certain values?

I want to render only specific objects if it contains certain values. For instance, if we have these data:
{
"product": [
{
"name": "laptop",
"markets": [
"Portugal",
"France"
],
"price": "1000"
},
{
"name": "PS5",
"markets": [
"Portugal",
"Spain"
],
"price": "400"
}
]
}
So I only want to render the objects which values match market's values. For example if I'm in the "Spain" category I only want to render the second object, because the first doesn't contain Spain in markets. So far I've tried filtering but it returns undefined:
const filtered = product.markets.filter(word => word === currentMarket)
You can do like this:
const filtered = products.filter(product => product.markets.some(m => m === currentMarket));
This means "give me all products whose product's markets include currently market"

Looping through multiple arrays in a single JSON file (Vanilla JS)

I am trying to populate my HTML template with data from a JSON file I have created. However, I have two different arrays in that file, each of them containing multiple objects, and I do not know how to loop through them since I need to loop through them in separate functions.
The JS code I have provided below works if I were to have one big array in the JSON file ("product" being the array I am looping through), the problem is that I need to loop through the "glass" and the "wood" arrays separately (in different functions). Ideally, the JS snippet below would loop through the "wood" array.
I have only fetched from one big array before, so I don't really know how to approach this issue. I know this must be something super easy, but I am stuck and would appreciate any hints I can get! Thanks in advance.
JS file:
function init() {
if (window.location.href.includes("wood")) {
fetchJson();
}
}
function fetchJson() {
fetch("products.json")
.then((res) => res.json())
.then(getWoodGallery(product));
}
function getWoodGallery(product) {
product.forEach(showWoodGallery);
}
/*--- display wood products ---*/
function showWoodGallery(product) {
console.log(product);
const woodTemplate = document.querySelector("#woodGalleryTemplate").content;
const woodTemplateCopy = woodTemplate.cloneNode(true);
const woodList = document.querySelector("#woodList");
woodTemplateCopy.querySelector("h2.name").textContent =
"Name: " + `${product.wood}`;
woodTemplateCopy.querySelector("p.dimensions").textContent =
"Dimensions: " + `${product.dimensions}`;
woodTemplateCopy.querySelector("h3.price").textContent =
"Price: " + `${product.price}`;
woodTemplateCopy.querySelector(".btn").textContent = `Buy Now`;
woodList.appendChild(woodTemplateCopy);
}
JSON file:
{
"wood": [
{
"id": "1",
"image": "http://mauriciolondono.be/wp/wp-content/uploads/2020/01/animales_1.jpeg",
"name": "Butterfly",
"dimensions": "30 x 45cm",
"price": 40,
"btn": ""
},
{
"id": "19",
"image": "http://mauriciolondono.be/wp/wp-content/uploads/2020/01/symmetry_4.jpeg",
"name": "Escher deconstructed",
"dimensions": "30 x 45cm",
"price": 20,
"btn": ""
}
],
"glass": [
{
"id": "20",
"image": "http://mauriciolondono.be/wp/wp-content/uploads/2020/01/vidrio_17.jpeg",
"name": "Juntos pero no revueltos",
"dimensions": "30 x 45cm",
"price": 20,
"btn": ""
},
{
"id": "21",
"image": "http://mauriciolondono.be/wp/wp-content/uploads/2020/01/vidrio_11.jpeg",
"name": "White & green",
"dimensions": "30 x 45cm",
"price": 20,
"btn": ""
}
]
}
You just need to loop over the JSON objects keys and conditionally run the function you need to run for that particular key.
function parse(payload) {
Object.keys(payload).forEach((key) => {
switch(key) {
case 'wood':
handleWood(payload[key]);
break;
case 'glass':
handleGlass(payload[key]);
break;
// so on...
}
})
}
Here, Object.keys will give you an array of all the keys of the object. We then iterate over the returned array with forEach running the callback for each iteration. Inside the callback we are just matching the key and running the required function.

MongoDB aggregate function is not returning the value of collection joined using JavaScript

I needed assistance in order to work out why the aggregate function is not responding the way I'd expect it to respond. This is a RESTful API service I've designed in which I am trying to connect collections with each other. Please note the following:
Collection: Season
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81"
}
Collection: Play
{
"_id": {
"$oid": "5c0fc4aafb6fc04dd6ea4d81"
},
"Name": "It was the first time",
"Description": "One of the best action heros in the entertainment industry until this day",
"ReleaseDate": "24/12/2010",
"EndingDate": "12/08/2012",
"Category": "Drama"
}
My implemented code in JavaScript
function getTestLookUp(db, collectionName, response, secondCollectionName){
console.log('First collection name: ' + collectionName + '\n' + 'Second collection name: ' + secondCollectionName);
db.collection(collectionName).aggregate([
{
$lookup:
{
from: secondCollectionName,
localField: 'PlayID',
foreignField: '_id',
as: 'requestedDetails'
}
}
]).toArray((err, res) => {
if(err){
console.log(err);
} else {
console.log(res);
response.status(200).json({
'Items': res
});
}
});
}
The response
{
"Items": [
{
"_id": "5c0fc60bfb6fc04dd6ea4e9a",
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81",
"requestedDetails": []
}
]
}
The things I've checked so far: the collection names are accurate, the ID is also accurate as I can search it up on the MLabs search feature. I don't understand as to why this is returning a empty 'requestedDetails' as I hoped it would return the item from the Play collection.
In addition to this, I would also appreciate if someone can point out how I can join multiple collections instead of 2.
I welcome any questions regarding this problem.
While still researching for this issue, I accidentally came across a another problem in which someone wrote a comment stating that "you might be comparing a String with ObjectID". This was the cause for this error as I obtain a String variable in return from the database and I am comparing the String variable with the _id which is expecting to see a ObjectID variable to complete the query. Therefore, meaning that my query/lookup is never matching these two variables.
The only way tackle this issue is to do a conversion (string to ObjectID) and then compare the values. However, since I'm using the version of ^3.1.10 of MongoDB, this functionality is not possible. Will need to update the version to 4.0 to be able to implement this functionality.
In order to rectify this issue, I managed to surround the foreign ID within $iod tags.
Before
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81"
}
After
{
"_id": {
"$oid": "5c0fc60bfb6fc04dd6ea4e9a"
},
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": {
"$oid": "5c0fc4aafb6fc04dd6ea4d81"
}
}
Response
{
"Items": [
{
"_id": "5c0fc60bfb6fc04dd6ea4e9a",
"Season": "1",
"TotalEpisode": "15",
"Name": null,
"Description": "First season with no name for this drama",
"PlayID": "5c0fc4aafb6fc04dd6ea4d81",
"Details": [
{
"_id": "5c0fc4aafb6fc04dd6ea4d81",
"Name": "It was the first time",
"Description": "One of the best action heros in the entertainment industry until this day",
"ReleaseDate": "24/12/2010",
"EndingDate": "12/08/2012",
"Category": "Drama"
}
]
}
]
}

Differences with API's when trying to pull data

I am having difficulty with a pulling some data from an API for a school project using Jquery.
If I use the following coinmaketcap API I get the following response
https://api.coinmarketcap.com/v1/ticker/bitcoin/
[
{
"id": "bitcoin",
"name": "Bitcoin",
"symbol": "BTC",
"rank": "1",
"price_usd": "8854.92",
"price_btc": "1.0",
"24h_volume_usd": "6759730000.0",
"market_cap_usd": "150480289107",
"available_supply": "16993975.0",
"total_supply": "16993975.0",
"max_supply": "21000000.0",
"percent_change_1h": "-0.13",
"percent_change_24h": "0.12",
"percent_change_7d": "8.3",
"last_updated": "1524459272"
}
]
I get am able to get the symbol for Bitcoin and place it into a variable by using this code
> $.getJSON('https://api.coinmarketcap.com/v1/ticker/btc/',
> function(data){
> var symbol = (data[0].symbol)
> })
Once I have it I can place it in a div.
However when I use cryptocompare API I don't get anything back
https://min-api.cryptocompare.com/data/coin/generalinfo?fsyms=BTC,&tsym=USD
$.getJSON('https://min-api.cryptocompare.com/data/coin/generalinfo?fsyms=BTC&tsym=USD', function(data){
var symbol = (data[0].Internal)
});
This is the response -
{
"Message": "Success",
"Type": 100,
"Data": [
{
"CoinInfo": {
"Id": "1182",
"Name": "BTC",
"FullName": "Bitcoin",
"Internal": "BTC",
"ImageUrl": "/media/19633/btc.png",
"Url": "/coins/btc/overview",
"Algorithm": "SHA256",
"ProofType": "PoW",
"NetHashesPerSecond": 27483320229.3688,
"BlockNumber": 518932,
"BlockTime": 600,
"BlockReward": 12.5,
"Type": 1,
"DocumentType": "Webpagecoinp"
},
"ConversionInfo": {
"Conversion": "direct",
"ConversionSymbol": "",
"CurrencyFrom": "BTC",
"CurrencyTo": "USD",
"Market": "CCCAGG",
"Supply": 16986575,
"TotalVolume24H": 380849.0498955779,
"SubBase": "5~",
"SubsNeeded": [
"5~CCCAGG~BTC~USD"
],
"RAW": [
"5~CCCAGG~BTC~USD~4~8875.23~1524460635~0.00477012~42.152119404000004~231254719~10820.885574747872~96327075.76938197~66326.58563159907~593473019.8524572~8823.46~8917.05~8804.2~8864.31~9065~8780.91~Bitfinex~7ffe9"
]
}
}
]
}
Why is the second piece of code not working? Please help!
The second API is returning an object (in JSON format), not an array - see how the first character is { and how it has keys and values? You need to access the appropriate property to get the value you want. [0] notation indicates you're trying to access the first element of the array, but the outer object is not an array in this situation.
$.getJSON('https://min-api.cryptocompare.com/data/coin/generalinfo?fsyms=BTC&tsym=USD',
function(data){
var symbol = data.Data[0].CoinInfo.Internal;
});
In both the cases, we are getting data in different form. So, To get the 'BTC' in variable .
for 1st case -> symbol = data[0] ['symbol']
for 2nd case -> symbol = data['Data'][0]['CoinInfo']['Internal']
one is an [array of JSON] while other is an [object having key 'Data' with array value].

Check if any value in jsonPath is repeated

I have a jsonPath as below
{ "book":
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 12.99
}
]}
And Want to check if any author name have got repeated?
I tried
$.book[?(#.author=='Nigel Rees')].find(1)
But, it always throws an exception that found nothing, how could I check that the author='Nigel Rees' occurrences i.e author='Nigel Rees' have a two books?
Depends what you are planning on doing if the authors names exists.
If you only want the objects with author of Nigel Reese you could use a filter.
var booksByNigelReese = book.filter( function(book, index) {
return book.author === 'Nigel Reese'
})
.filter() takes a function that takes the book and index, chooes to accept or rejcet the book into a new array depending if the result of the function is true or false

Categories