I want to create searchable input but something went wrong thats why this is not working. How can i fix it?
My Code:-
import React, {useState} from 'react';
import "./styles.css";
export default function App() {
const country_list = [
"Argentina",
"Australia",
"Belgium",
"Belize",
"China",
"Iceland",
"India",
"Indonesia",
"Iran",
"Poland",
"Portugal",
"Romania",
"Russia",
"Saudi Arabia",
"South Africa",
"South Korea",
"Swaziland",
"Sweden",
"Switzerland"
];
const [inputVal, setInputVal] = useState();
country_list.filter(country => {
if(inputVal === ''){
return country;
} else if (country.toLowerCase().includes(inputVal.toLowerCase())) {
return country;
}
});
return (
<div className="App">
<input type="text" onChange={event => setInputVal(event.target.value)} />
{inputVal}
{country_list.map((val, index)=>(
<>
<div key={index}>
{val}
</div>
</>
))}
</div>)
}
Thanks for your efforts!
To make that code work you should fix some strings. I posted comments bellow. Also I recommend move your changable variables like country_list to useState because the state of your app can get out of sync with the view.
import React, { useState } from 'react';
import "./styles.css";
export default function App() {
let country_list = [
"Argentina",
"Australia",
"Belgium",
"Belize",
"China",
"Iceland",
"India",
"Indonesia",
"Iran",
"Poland",
"Portugal",
"Romania",
"Russia",
"Saudi Arabia",
"South Africa",
"South Korea",
"Swaziland",
"Sweden",
"Switzerland"
] // change country_list to let so we could reasssign it;
const [inputVal, setInputVal] = useState(''); // use empty string in useState as initial state for you inputVal
country_list = country_list.filter(country => {
if (inputVal === '') {
return country;
} else if (country.toLowerCase().includes(inputVal.toLowerCase())) {
return country;
}
}); // function filter in JS create new array everytime instead of changing the old one. You should reassign your country_list variable
return (
<div className="App">
<input type="text" onChange={event => setInputVal(event.target.value)} />
{inputVal}
{country_list.map((val, index) => (
<>
<div key={index}>
{val}
</div>
</>
))}
</div>)
}
I want to create searchable input but something went wrong thats why this is not working. How can i fix it?
Your code seems fine, just move it to the return block, before mapping:
{country_list.filter(country => {
if(inputVal === ''){
return country;
} else if (country.toLowerCase().includes(inputVal.toLowerCase())) {
return country;
}
}).map((val, index)=>( ... )}
I believe that using this going to work, move your code to the return () and map the returned value from the filter try this code below and its gonna work :)
{countryList
.filter((country) => {
if (inputVal == "") {
return country;
} else if (country.toLowerCase().includes(inputVal.toLowerCase())) {
return country;
}
})
.map((Val, index) => {
return (
<div key={index}>
{val}
</div>
);
})}
You can do like this if you want data
import React, { useState } from "react";
import "./styles.css";
export default function App() {
const country_list = [
"Argentina",
"Australia",
"Belgium",
"Belize",
"China",
"Iceland",
"India",
"Indonesia",
"Iran",
"Poland",
"Portugal",
"Romania",
"Russia",
"Saudi Arabia",
"South Africa",
"South Korea",
"Swaziland",
"Sweden",
"Switzerland"
];
const [inputVal, setInputVal] = useState(" ");
const countryList = country_list.filter((country) => {
if (inputVal === "") {
return country;
} else if (country.toLowerCase().includes(inputVal.toLowerCase())) {
return country;
}
return country;
});
console.log(countryList);
return (
<div className="App">
<input
type="text"
onChange={(event) => setInputVal(event.target.value)}
/>
{inputVal}
{countryList.map((val, index) => (
<>
<div key={index}>{val}</div>
</>
))}
</div>
);
}
Related
I am kinda fresh to react and useState hooks (still learing).
I want to create show more/less button with use of Array and React hooks.
I came across this code with exact result i want to achieve - showing some part of an array, and then showing the rest/ returning to previous state.
The thing is, the code is written with use of class components. I never even learned them, useState is more recent.
How to achieve something like this, but with use of state hook (useEffect?) if is it possible ?
https://jsbin.com/wowaluwipu/1/edit?html,js,output
class Application extends React.Component {
constructor() {
super()
this.state = {
cars: [
{ "name" : "Audi", "country" : "Germany"},
{ "name" : "BMW", "country" : "Germany" },
{ "name" : "Chevrolet", "country" : "USA" },
{ "name" : "Citroen", "country" : "France" },
{ "name" : "Hyundai", "country" : "South Korea" },
{ "name" : "Mercedes-Benz", "country" : "Germany" },
{ "name" : "Renault", "country" : "France" },
{ "name" : "Seat", "country" : "Spain" },
],
itemsToShow: 3,
expanded: false
}
this.showMore = this.showMore.bind(this);
}
showMore() {
this.state.itemsToShow === 3 ? (
this.setState({ itemsToShow: this.state.cars.length, expanded: true })
) : (
this.setState({ itemsToShow: 3, expanded: false })
)
}
render() {
return <div className="container">
<h3>Click show more to see more data</h3>
<div className="row">
<h3>List of Cars</h3>
<ul>
{this.state.cars.slice(0, this.state.itemsToShow).map((car, i) =>
<li key={i}>{car.name} - {car.country}</li>
)}
</ul>
</div>
Either way, mine works as well as the others. Just in a bit of a different way.
import React, { useState } from 'react'
function Stacks() {
const [itemsToShow, setItemsToShow] = useState(3);
const cars = [
{ "name" : "Audi", "country" : "Germany"},
{ "name" : "BMW", "country" : "Germany" },
{ "name" : "Chevrolet", "country" : "USA" },
{ "name" : "Citroen", "country" : "France" },
{ "name" : "Hyundai", "country" : "South Korea" },
{ "name" : "Mercedes-Benz", "country" : "Germany" },
{ "name" : "Renault", "country" : "France" },
{ "name" : "Seat", "country" : "Spain" },
];
const showmore = () => {
setItemsToShow(cars.length)
}
const showless = () => {
setItemsToShow(3)
}
return (
<div>
{cars.slice(0, itemsToShow).map((car, index) => <li key={index}>{car.name} - {car.country} </li>)}
{(itemsToShow === 3) ? <button onClick={showmore}>Show More</button>: <button onClick={showless}>Show Less</button>}
</div>
)
}
Might not be the efficient way, the only difference is I took out the onliner code from show more and made a separate function show less that resets the original state value which is 3.
I have the same problem when I was just starting in React that I normally see Class Components in tutorials.
hello i had the same problem ,but thanks to help of others it is much clearer
(i cloudnt test if it works myself but that should be it)
import { useState } from "react";
function App() {
// const [state, setstate] = useState(initialState) // this is how it initially is
const [data, setData] = useState({
cars: [
{ name: "Audi", country: "Germany" },
{ name: "BMW", country: "Germany" },
{ name: "Chevrolet", country: "USA" },
{ name: "Citroen", country: "France" },
{ name: "Hyundai", country: "South Korea" },
{ name: "Mercedes-Benz", country: "Germany" },
{ name: "Renault", country: "France" },
{ name: "Seat", country: "Spain" },
],
itemsToShow: 3,
}); // i named it data youcan name it whatever suits you
const showMore = () => {
data.itemsToShow === 3
? // ...data is a spread of the state, that means have all the data and change that
// particular one, in that case "itemsToShow"
setData({ ...data, itemsToShow: data.cars.length })
: setData({ itemsToShow: 3 });
};
return (
<div className="container">
<h3>Click show more to see more data</h3>
<div className="row">
<h3>List of Cars</h3>
<ul>
{data.cars.slice(0, data.itemsToShow).map((car, i) => (
<li key={i}>
{car.name} - {car.country}
</li>
))}
</ul>
</div>
// if the items you want to show are equal to the legth of your car list
then hide the button
{data.itemsToShow < data.cars.length && (
<button onClick={showMore}>Show more</button>
)}
</div>
);
}
export default App;
generally you get rid of ,"this", "this.state", and instead of "this.setState" you put your hook directly like "setNewThings" or "SetCrazyStuff", or what so..
You'll get the hang of it with more practice, hope that helps
I am new to React, I already have a list of movies in a dropdown but i am trying to fetch the name, age and height from this json data and display it, i am suppose to get all characters that appear in the movie(http://swapi.dev/api/films) and list the name,
gender, and height:
This is the character list from one of the films i fetched from the api
"results": [
{
"title": "A New Hope",
"episode_id": 4,
"director": "George Lucas",
"producer": "Gary Kurtz, Rick McCallum",
"release_date": "1977-05-25",
"characters": [
"http://swapi.dev/api/people/1/",
"http://swapi.dev/api/people/2/",
"http://swapi.dev/api/people/3/",
"http://swapi.dev/api/people/4/",
"http://swapi.dev/api/people/5/",
"http://swapi.dev/api/people/6/",
"http://swapi.dev/api/people/7/",
"http://swapi.dev/api/people/8/",
"http://swapi.dev/api/people/9/",
"http://swapi.dev/api/people/10/",
"http://swapi.dev/api/people/12/",
"http://swapi.dev/api/people/13/",
"http://swapi.dev/api/people/14/",
"http://swapi.dev/api/people/15/",
"http://swapi.dev/api/people/16/",
"http://swapi.dev/api/people/18/",
"http://swapi.dev/api/people/19/",
"http://swapi.dev/api/people/81/"
],
Then the characters still has /people/ endpoints
{
"name": "Luke Skywalker",
"height": "172",
"mass": "77",
"hair_color": "blond",
"skin_color": "fair",
"eye_color": "blue",
"birth_year": "19BBY",
"gender": "male",
"homeworld": "http://swapi.dev/api/planets/1/",
"films": [
"http://swapi.dev/api/films/1/",
"http://swapi.dev/api/films/2/",
"http://swapi.dev/api/films/3/",
"http://swapi.dev/api/films/6/"
],
Here is my code:
import React, { Component } from 'react'
import Select from 'react-select'
import axios from 'axios'
export default class Contact extends Component {
constructor(props){
super(props)
this.state = {
selectOptions : [],
opening_crawl: "",
title: '',
characters: ''
}
}
async getOptions(){
const res = await axios.get('https://swapi.dev/api/films/')
const data = res.data
const options = data.results.map(d => ({
"value" : d.opening_crawl,
"label" : d.title,
"actors" : d.characters
}))
this.setState({selectOptions: options})
}
handleChange = (e) => {
this.setState({opening_crawl:e.value, title:e.label, characters: e.actors})
}
getCharacters(characters){
const options = characters.map(d => ({
"name" : d.name,
"gender" : d.gender,
"height" : d.height
}))
this.setState({chars: options})
}
debugger;
componentDidMount(){
this.getOptions()
this.getCharacters()
}
render() {
console.log(this.state.selectOptions)
return (
<div>
<Select options={this.state.selectOptions} onChange={this.handleChange} />
<marquee width="1200px" direction="right" height="50px" color='white'>
{this.state.opening_crawl}
</marquee>
<p>
{this.chars}
</p>
</div>
)
}
}
this line of code get the error
componentDidMount(){
this.getOptions()
this.getCharacters() // you pass nothing to this function so you got that error
}
This question already has answers here:
Filter array of objects on all properties value
(3 answers)
Filter array of objects by multiple properties and values
(4 answers)
Closed 1 year ago.
I am trying to filter through a few objects in a massive array, please find a few lines of it below:
var dest = [{
"city": "Glendale",
"country": "Armenia",
"admin_name": "Adana Eyalet"
}, {
"city": "Globe",
"country": "United States, USA",
"admin_name": "Arizona"
}, {
"city": "Kingman-Butler",
"country": "United Kingdom",
"admin_name": "Wales"
}]
And I have only one input field to search through these objects - city, country.
I am using the following code:
var admin_name = dest.filter(function(item) {
return item['admin_name'].toLowerCase().indexOf(searchText.toLowerCase()) != -1
});
But haven't got a clue how to achieve my task. Sorry just started learning javascript.
Thank you for your help.
check this one:
var dest = [
{ city: "Glendale", country: "Armenia", admin_name: "Adana Eyalet" },
{ city: "Globe", country: "United States, USA", admin_name: "Arizona" },
{ city: "Kingman-Butler", country: "United Kingdom", admin_name: "Wales" },
];
function searchInAllProp(object, textsearch) {
for (a in object)
if (object[a].includes(textsearch))
return object;
return undefined;
}
let f = dest.filter(t => searchInAllProp(t, "United"));
console.log(f);
Had too much time to make it interactive.
const searchBtn = document.querySelector("#search-btn");
var dest = [
{ "city": "Glendale", "country": "Armenia", "admin_name": "Adana Eyalet" },
{ "city": "Globe", "country": "United States, USA", "admin_name": "Arizona" },
{ "city": "Kingman-Butler", "country": "United Kingdom", "admin_name": "Wales" }
];
searchBtn.addEventListener('click', () => {
const searchText = document.querySelector("#search-text").value;
const radio = document.querySelectorAll("input[type=radio]");
const arr = Array.from(radio);
const searchKey = arr.find(item => item.checked).id;
if(searchKey) {
const filteredArray = dest.filter(item => {
return item[searchKey].toLowerCase() === searchText.toLowerCase()
});
document.querySelector('span').innerHTML = filteredArray.length ? JSON.stringify(filteredArray) : "No results found";
}
});
<input type="text" id="search-text" />
<br />
<br />
<input type="radio" id="city" name="search-param">
<label>City</label>
<input type="radio" id="country" name="search-param">
<label>Country</label>
<br />
<br />
<button type="button" id="search-btn"> Search !! </button>
<br />
<br />
<span id="results"></span>
I hope someone will be able to help me or at least guide me on what topics to look for answers
I'm newbie at React. I have a code that allows me to filter the list that is in the items object. And there's no problem with that. But I would like to use prepared json file instead, but when I try to refer to "city" I get a bug at the onTextChanged method (Cannot read property 'sort' of undefined). I'm not exactly sure how I should relate to next levels in json. I tried something like that if we take the CityList as a definition of items.
this.items.city.sort().filter(...)
This is the whole component
import React, { Component } from 'react';
import "./HiddenTownList.css";
//import CityList from "./JsonCities";
class HiddenTownList extends Component {
items = [
"Warsaw",
"New York",
"London"
];
state = {
suggestion: []
};
onTextChanged = (e) => {
const value = e.target.value;
let suggestion = [];
if (value.length > 0) {
const regex = new RegExp(`^${value}`, 'i');
suggestion = this.items.sort().filter(v => regex.test(v));
this.setState(() => ({ suggestion }))
}
else {
this.setState(() => ({ suggestion }));
}
}
renderSuggestions() {
const { suggestion } = this.state;
if (suggestion.length === 0) {
return null;
}
else {
return (
<ul>{suggestion.map((city) => <li>{city}</li>)}</ul>
)
}
}
render() {
return (
<>
<input onChange={this.onTextChanged}></input>
{this.renderSuggestions()}
</>
)
}
};
export default HiddenTownList;
JSON code sample
const CityList = [
{
"id": "1",
"city": "Katowice",
"lat": "50.258415",
"lng": "19.027545",
"country": "Poland",
"admin": "Śląskie"
},
{
"id": "2",
"city": "Warsaw",
"lat": "52.25",
"lng": "21",
"country": "Poland",
"admin": "Mazowieckie"
},
{
"id": "3",
"city": "Łódź",
"lat": "51.75",
"lng": "19.466667",
"country": "Poland",
"admin": "Łódzkie"
}]
You are trying to perform sort function on city. Which is variable. Thats way it is giving undefined value. Sort always work on array field.
this is my first post and was extremely confused on how to map over the json data correctly.
The problem comes from when you map the user address property with Object.keys, everything is mapping over fine until it gets to the "geo" property values. What is the solution to map and render over every property easier?
const style = {
list: {
listStyle: "none"
}
};
const data = [
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "Sincere#april.biz",
address: {
street: "Kulas Light",
suite: "Apt. 556",
city: "Gwenborough",
zipcode: "92998-3874",
geo: {
lat: "-37.3159",
lng: "81.1496"
}
},
phone: "1-770-736-8031 x56442",
website: "hildegard.org",
company: {
name: "Romaguera-Crona",
catchPhrase: "Multi-layered client-server neural-net",
bs: "harness real-time e-markets"
}
}
];
function App() {
return (
<div className="App">
<ul style={style.list}>
{data.map(user => {
return (
<Fragment key={user.id}>
<li>{user.username}</li>
<ul style={style.list}>
{Object.keys(user.address).map(key => {
return (
<li>
{key} {user.address[key]}
</li>
);
})}
</ul>
</Fragment>
);
})}
</ul>
</div>
);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
Use object keys on geo, in your li check if key is equal to geo, then map over it.
<li>
{key} {key === 'geo' ? Object.keys(user.address[key]).map(geo => <i>{user.address[key][geo]}</i>) : user.address[key] }
</li>
// Get a hook function
const {useState} = React;
const style = {
list: {
listStyle: "none"
}
};
const data = [
{
id: 1,
name: "Leanne Graham",
username: "Bret",
email: "Sincere#april.biz",
address: {
street: "Kulas Light",
suite: "Apt. 556",
city: "Gwenborough",
zipcode: "92998-3874",
geo: {
lat: "-37.3159",
lng: "81.1496"
}
},
phone: "1-770-736-8031 x56442",
website: "hildegard.org",
company: {
name: "Romaguera-Crona",
catchPhrase: "Multi-layered client-server neural-net",
bs: "harness real-time e-markets"
}
}
];
function App() {
return (
<div className="App">
<ul style={style.list}>
{data.map(user => {
return (
<React.Fragment key={user.id}>
<li>{user.username}</li>
<ul style={style.list}>
{Object.keys(user.address).map(key => {
return (
<li>
{key} {key === 'geo' ? Object.keys(user.address[key]).map(geo => <i>{`${geo}: ${user.address[key][geo]} `}</i>) : user.address[key] }
</li>
);
})}
</ul>
</React.Fragment>
);
})}
</ul>
</div>
);
}
// Render it
ReactDOM.render(
<App />,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.4/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.4/umd/react-dom.production.min.js"></script>
<div id="react"></div>
Just add an if statement for geo key and return your desired JSX.
{
Object.keys(user.address).map(key => {
if (key === "geo") {
Object.keys(user.address[key]).map(geoKey => {
return (
<li>
{geoKey} {user.address[key][geoKey]}
</li>
);
});
} else {
return (
<li>
{key} {user.address[key]}
</li>
);
}
});
}