Get items by name from JSON based on user input id react - javascript

Hey how would I go about getting items by name from a JSON file based on what a user inputs? I have a JSON file that has an id and name. I want the user to put in a number and then display the item name associated with that id number. I am using ReactJS for this. Any advice would be greatly appreciated. thank you

You can read JSON file as Javascript Object or Array.
I use react hooks. Sorry my English very bad.
import { useState } from 'react';
import jsonData from './data.json';
export default function Test() {
const [name, setName] = useState('');
const onChange = (e) => {
// jsonData is javascript array when import it
const data = jsonData.find((d) => d.id == e.target.value);
if (data) {
setName(data.name);
}
};
return (
<div>
<input onChange={onChange} />
<p>Name: {name}</p>
</div>
);
}
JSON file for test:
[
{
"id": 1,
"name": "abc"
},
{
"id": 2,
"name": "def"
},
{
"id": 3,
"name": "ghi"
}
]

Related

React, local json file won't display

I have a local json which is returning all values on console.log so I know the path is correct. However when I am trying to pull an input value of name from it, it gives me error uni.map is not a function.
What am I'm missing, any help will be fab :).
import { useState } from 'react'
import axios from 'axios'
import Uni from './Uni'
function Unis() {
const [unis, setUnis] = useState([])
const [query, setQuery] = useState('')
function handleSearchQuery(e) {
e.preventDefault()
setQuery(e.target.value)
}
async function searchUnis(e) {
e.preventDefault()
console.log()
var response = await axios.get(data.json)
setUnis(response.data)
}
return (
<div>
<input value={query} onChange={handleSearchQuery} />
<button onClick={searchUnis}>Search</button>
<ul>
{
unis.map(function(i, index){
return (
<li key={index}>
<Uni name={i.name} />
</li>
)
})
}
</ul>
</div>
)
}
export default Unis;
data.json
{
"data": [
{
"name": "xxx",
"years": "2022"
},
{
"name": "hhh",
"years": "2021"
}
]
}
Good Luck,
You have used data.json directly without import.
var response = await axios.get(data.json)
Ans:
Step 1:
Import the data.json file in Unis file.
import Data from './data.json';
Step 2:
Use the data like below.
var response = await axios.get(Data.data);

How can I fetch data from Firebase into my React App

Please, I am very new to React.js and having this challenge of fetching dating from Firebase to populate this. I want to be able to fetch a single properties and not all of them - eg (title, body and price).
useFetch is a custom hook I created inside the project to handle the fetch from firebase.
What am I not getting right here please?
import { useParams } from 'react-router-dom';
import useFetch from '../UseFetch';
import '../courseDetails/CourseDetails.css';
import { useState, useEffect } from 'react';
import React from 'react'
const CourseDetails = () => {
const { id } = useParams();
const { data:details, isLoading } = useFetch('https://tutorialwebsite-460f1-default-rtdb.firebaseio.com/courses.json');
console.log(details);
return (
<div className="course-detail">
<h2>{ id }</h2>
<div>
<p>{details.description}</p>
</div>
</div>
)
}
export default CourseDetails
Here's the object loaded from the API:
{
"-MaebRkqKfjLG8heBbSu": {
"body": "qwerqwer",
"description": "wqerqwetqwe",
"imageUrl": "wdfwerw",
"price": "werqwertwer",
"title": "title 1"
}
}
How can I access the description?
Thank you everyone for your response but I was able to solve my problem. So what I did was changed into a used fake json api instead of firebase I was initially using. Then I was able to dynamically route to a specific page based of the unique id after fetching the data from firebase and then used conditional rendering to output the data on the page. However, I would have loved to know how to do this using using firebase.
const CourseDetails = () => {
const { id } = useParams();
const { data:details, isLoading } = useFetch('http://localhost:8000/courses/' + id);
console.log(details)
return (
<div className="course-detail">
{isLoading && <div>Loading...</div>}
{details && <div>{details.body}</div> }
</div>
)
}
export default CourseDetails

How to use right, reselect in react-redux aplication

I have an application where user can search data depending by his input. In my application i try to use reselect.
import React, { useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { searchPersonAction } from "./store";
const Search = () => {
const dispatch = useDispatch();
const selector = useSelector((s) => s);
const search = (e) => {
const txt = e.target.value;
dispatch(searchPersonAction(txt));
};
return (
<div>
<input onChange={search} placeholder="search" />
<ul>
{selector.name.map((p) => (
<li key={p.name}>{p.name}</li>
))}
</ul>
</div>
);
};
export default Search;
In my store i have an array of persons like this:
export const persons = [
{
name:"jack",
age: 2
},
{
name:"Jim",
age: 14
},
{
name:"July",
age: 92
},
{
name:"Bill",
age: 1
},
{
name:"Carl",
age: 72
},
]
Now, when user search something, in the list appears the results according to the name which was searched by the user.
Question: Is the reselect usefull (protects from to many re-renders) in my case or not? Or using useSelector, in the case above is enought?
I don't think reslect here will be necessary. You can use useMemo to achieve the same result.
import React, { useEffect, useMemo } from "react";
import { useDispatch, useSelector } from "react-redux";
import { searchPersonAction } from "./store";
const Search = () => {
const dispatch = useDispatch();
const persons = useSelector((s) => s.persons);
const [query, updateQuery] = useState('');
const searchedPersons = useMemo(() => persons.filter(p => p.name.includes(query)), [query]);
const search = (e) => {
updateQuery(e.target.value);
};
return (
<div>
<input onChange={search} placeholder="search" />
<ul>
{searchedPersons.map((p) => (
<li key={p.name}>{p.name}</li>
))}
</ul>
</div>
);
};
export default Search;
reselect will be useful if you get array or object from store for example:
store
state = {
persons: [
{
name:"Jack",
age: 2
},
{
name:"Jane",
age: 14
},
]
}
if you used selector from react-redux and if your typed 'J' in the search field and used searchPersonAction action, then it will change the array of persons in the store, but array stayed the same.
state = {
persons: [
{
name:"Jack",
age: 2
},
{
name:"Jane",
age: 14
},
]
}
then you receive rerender regardless of whether the data in the array has changed or not.
But if you use reselect and when your typed 'Ja' in the search field, it will be the same array, then you will not get a repeated render, because reselect will memoize data

Passing data to lodash map() function - functional components

This is example of my products.json
{
"products": [
{
"product_id": 1,
"product_name": "M-Z-8Nm",
"supplier_id": 1,
"product_cat": "Motori",
"product_subcat": "Zglobni motori",
"product_char": "8Nm",
"product_uom": "kom",
"product_quantity": "20",
"product_commentar": ""
},
{
"product_id": 2,
"product_name": "M-P-10Nm",
"supplier_id": 1,
"product_cat": "Motori",
"product_subcat": "Pomoćni motori",
"product_char": "10Nm",
"product_uom": "kom",
"product_quantity": "13",
"product_commentar": ""
}
]
}
Now, in component under i am mapping options for Select field from products.json ( react-select ) and return it. In this example i am mapping product-name as option for select button.
I would like to make this component reusable so i could pass data with props and use it (ie. product-id instead of product-name. Data from props are stored in const extractProps which is typeof String (but dont need to be).
I have problem replacing key from products product_name with data from props extractProps.
ReactSelectComponent.js:
import React from "react";
import Select from "react-select";
import FetchDataCustomHook from "./FetchDataCustomHook.js";
import _ from "lodash";
const ReactSelectComponent = (props) => {
// extractProps is typeof string and need to replace "product_name"
const extractProps = props.propsFromForm
const options = _.map(
FetchDataCustomHook(),
function (products) {
return {label: products.product_name, value: products.product_name}
});
return (<Select options={options}/>)
}
export default ReactSelectComponent;
You don't really need lodash to accomplish that map, this is a solution using pure js:
const ReactSelectComponent = ({property}) => {
const options = products.map((product) => {
return { value: product[property], label: product[property] }
});
return (<Select options={options}/>);
}
If you want to use lodash then it the options would be like this:
const options = _.map(products, (product) => {
return { value: product[property], label: product[property] }
})
And this is how you called the component <ReactSelectComponent property='product_name' />.
I stored the json you posted as the products variable.

Problem with using deeper nested data fetched from API

I encountered a problem when I try to fetch some data from PokeAPI. Here's my code for PokemonCard component.
import React, { useEffect, useState } from "react";
import axios from "axios";
const PokemonCard = ({ pokemonID }) => {
const [pokemon, setPokemon] = useState({});
useEffect(() => {
(async () => {
const result = await axios.get(
`http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
);
setPokemon(result.data);
})();
// console.log(pokemon.weight)
}, [pokemonID]);
return (
<div className="pokemon">
{pokemon.sprites.front_default}
</div>
);
};
export default PokemonCard;
Everything works properly when I try to reach data like: pokemon.weight or pokemon.base_experience. But I get errors when I try to use some deeper nested variables.
pokemon.sprites.front_default gives me an error TypeError:
Cannot read property 'front_default' of undefined.
Here's a sample of data from API:
"name": "bulbasaur",
"order": 1,
"species": {
"name": "bulbasaur",
"url": "https://pokeapi.co/api/v2/pokemon-species/1/"
},
"sprites": {
"back_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/1.png",
"back_female": null,
"back_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/back/shiny/1.png",
"back_shiny_female": null,
"front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/1.png",
"front_female": null,
"front_shiny": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/shiny/1.png",
"front_shiny_female": null
},
"stats": [
{
"base_stat": 45,
"effort": 0,
"stat": {
"name": "hp",
"url": "https://pokeapi.co/api/v2/stat/1/"
}
}
],
"types": [
{
"slot": 2,
"type": {
"name": "poison",
"url": "https://pokeapi.co/api/v2/type/4/"
}
},
{
"slot": 1,
"type": {
"name": "grass",
"url": "https://pokeapi.co/api/v2/type/12/"
}
}
],
"weight": 69
PS. Is it a good practice to make about 150 separate calls to API in every child component? Or should I somehow do it with one call? Thank you.
You were trying to access a key inside an undefined key of pokemon variable. Please check the updated line where you are actually rendering.
{pokemon.sprites ? pokemon.sprites.front_default : ''}
As Pokemon is an empty object before the api fetches the data and
updates to the state, so pokemon.sprites is actually undefined.
import React, { useEffect, useState } from "react";
import axios from "axios";
const PokemonCard = ({ pokemonID }) => {
const [pokemon, setPokemon] = useState({});
useEffect(() => {
(async () => {
const result = await axios.get(
`http://pokeapi.co/api/v2/pokemon/${pokemonID + 1}`
);
setPokemon(result.data);
})();
// console.log(pokemon.weight)
}, [pokemonID]);
return (
<div className="pokemon">
//this should work for you
{pokemon.sprites ? pokemon.sprites.front_default : ''}
</div>
);
};
export default PokemonCard;
Gets much easier in Optional chaining (?.)
pokemon.sprites?.front_default

Categories