React rest call map result to selectbox with avatar and label per option - reactjs

Hi here is rest response:
[
{
"self": "https://your-domain.atlassian.net/rest/api/3/project/EX",
"id": "10000",
"key": "EX",
"name": "Example",
"avatarUrls": {
"48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10000",
"24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10000",
"16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10000",
"32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10000"
},
"projectCategory": {
"self": "https://your-domain.atlassian.net/rest/api/3/projectCategory/10000",
"id": "10000",
"name": "FIRST",
"description": "First Project Category"
},
"simplified": false,
"style": "classic",
"insight": {
"totalIssueCount": 100,
"lastIssueUpdateTime": "2022-12-08T07:09:19.702+0000"
}
},
{
"self": "https://your-domain.atlassian.net/rest/api/3/project/ABC",
"id": "10001",
"key": "ABC",
"name": "Alphabetical",
"avatarUrls": {
"48x48": "https://your-domain.atlassian.net/secure/projectavatar?size=large&pid=10001",
"24x24": "https://your-domain.atlassian.net/secure/projectavatar?size=small&pid=10001",
"16x16": "https://your-domain.atlassian.net/secure/projectavatar?size=xsmall&pid=10001",
"32x32": "https://your-domain.atlassian.net/secure/projectavatar?size=medium&pid=10001"
},
"projectCategory": {
"self": "https://your-domain.atlassian.net/rest/api/3/projectCategory/10000",
"id": "10000",
"name": "FIRST",
"description": "First Project Category"
},
"simplified": false,
"style": "classic",
"insight": {
"totalIssueCount": 100,
"lastIssueUpdateTime": "2022-12-08T07:09:19.702+0000"
}
}
]
I want to make select bobx having
<option value={data.id}><Img {data.16x16}/>data.label</option>
But result would be all projects if company has multiple projects so select box values have to map or loop into react
<Select options="result">
Im stuck as my code displays only label not any image there.
Another problem is that using data.avatarUrls.16x16 does not compile. VSCode says expecting "," and puts red underline to 16x16
Here is my code a lot is broken here because I have tested a lot ways but no luck
import React, { useState } from 'react';
import Select from 'react-select'
import { components } from 'react-select';
//Kun selectbox
const handleChange = event => {
//console.log(event.target.value);
setSelected(event.target.value);
};
//Palauttaa projectit json taulukon
const getProjects = async () => {
//Matti tähän sitten atlasion cmpany projection haku
const response = await api.asUser().requestJira(route`/rest/api/3/project`, {
headers: {
'Accept': 'application/json'
}
});
const data = await response.json();
//Mapataa hausta tarvittavat tiedot
const result = data.map(function (item, i) {
console.log('test');
return [
{
label: item.name,
value: item.id,
avatar: item.avatarUrls.16x16
}
]
})
return result
}
function Projects() {
//haetaan atlasiansita projectit array
const p = getProjects
//asetetaan state selectbox muutokselle
const [selected, setSelected] = useState(p.id);
return (
<div className='projects'>
<Select
className='select-projects'
options={p}
onChange={handleChange}
/>
</div>
);
}
export default Projects

Related

How to use json data for react-select?

How can I use a json data from a .json file and use it as options of react-select?
Currently I am using some options from the example they have in the documentation.
Here is my jsx code -
import React, { useEffect } from "react";
import Button from "#ui/button";
import Select from "react-select";
import { useState } from "react";
const options = [
{ value: "chocolate", label: "Chocolate" },
{ value: "strawberry", label: "Strawberry" },
{ value: "vanilla", label: "Vanilla" },
];
function Company({}) {
const [selectedOption, setSelectedOption] = useState(null);
return (
<>
<form className="company-form">
<div className="p-3 pt-0">
<label className="mt-3" htmlFor="jurisdiction-code">
Company Jurisdiction
</label>
<Select
className="text-xl"
defaultValue={selectedOption}
onChange={setSelectedOption}
options={options}
required
isClearable={true}
id="jurisdiction-code"
/>
</div>
<div className="mt-5">
<Button size="medium" fullwidth>
Submit
</Button>
</div>
</form>
</>
);
}
export default Company;
I have a separate json file for the options.
Here is my jurisdiction.json file code -
[
{
"id": 1,
"jurisdiction": "Alabama (US)",
"code": "us_al"
},
{
"id": 2,
"jurisdiction": "Alaska (US)",
"code": "us_ak"
},
{
"id": 3,
"jurisdiction": "Arizona (US)",
"code": "us_az"
},
{
"id": 4,
"jurisdiction": "Arkansas (US)",
"code": "us_ar"
},
{
"id": 5,
"jurisdiction": "California (US)",
"code": "us_ca"
}
]
I want to display jurisdiction and use code as the value.
How can I do that?
If the JSON data file is located in the public directory then you can use a useEffect hook to issue a fetch to retrieve it and save it into local state.
Example:
Assuming JSON file is located in public/data/data.json
function Company() {
const [selectedOption, setSelectedOption] = useState();
const [options, setOptions] = useState([]);
useEffect(() => {
const getOptions = async () => {
try {
const response = await fetch("/data/data.json");
const options = await response.json();
console.log(options);
setOptions(
options.map(({ id, jurisdiction, code }) => ({
id,
label: jurisdiction,
value: code
}))
);
} catch (error) {
// ignore
}
};
getOptions();
}, []);
return (....);
}

React Apex Chart Data, Image and API

How to modify series and options, i want to make chart type=treemap on react hooks like this
i have name, user and percent on api.
{
"data": [
{
"id": "1",
"name": "Pisces",
"user": "95",
"percent": "3.15%",
},
{
"id": "2",
"name": "Leo",
"user": "50",
"percent": "2.35%",
},
{
"id": "3",
"name": "Capricorn",
"user": "91",
"percent": "3.12%",
}
]
}
and source for apex https://apexcharts.com/docs/chart-types/treemap-chart/
import React, { useState,useEffect } from 'react';
import axios from 'axios';
import './App.css';
import Chart from 'react-apexcharts'
import icUser from './image/profile-user.png'
import icChart from './image/pie-chart.png'
const App =()=> {
const [dataUser,setDataUser]=useState([])
useEffect(() => {
axios.get("http://localhost:4000/data")
.then(response =>{
setDataUser(response.data)
}).catch(e => {
alert(e);
})
}, [])
const series = {.....}
const options = {.....}
return (
<div>
<Chart options={options} series={series} height={350} type="treemap"/>
</div>
)
}
export default App
In series you need to pass an array like this, Where x is the name, and y percentage. and In option you can modify the treemap chart like change height, type, plotOptions and more...
const App = () => {
const [dataUser, setDataUser] = useState([])
useEffect(() => {
axios.get("http://localhost:4000/data")
.then(response => {
setDataUser(response.data)
}).catch(e => {
alert(e);
})
}, [])
const seriesData = [];
const options = {}
dataUser.map((val) => {
seriesData.push(
{
x: val.name, //
y: val.percent //
}
);
});
const series = [{ data: seriesData }];
return (
<div>
<Chart options={options} series={series} height={350} type="treemap" />
</div>
)
}
export default App

React Autocomplete matching highlighted word

I have autocompleted features. when I search for something we will get the data accordingly. But I want to add one more feature like when we search data will come as well as whatever I typed in the search box that character should be highlighted in yellow color.
Here is the piece of code I have written.
import logo from './logo.svg';
import './App.css';
import React, { useState } from "react";
function App() {
const [names, setnames] = useState([{
"name": "Barbara-anne"
}, {
"name": "Debi"
}, {
"name": "Cara"
}, {
"name": "Cristin"
}, {
"name": "Jocelyne"
}, {
"name": "Joellyn"
}, {
"name": "Elmo"
}, {
"name": "Ivette"
}, {
"name": "Lea"
}, {
"name": "Michel"
}, {
"name": "Leigha"
}, {
"name": "Titus"
}, {
"name": "Nollie"
}, {
"name": "Celle"
}, {
"name": "Thea"
}, {
"name": "Brynn"
}, {
"name": "Sloane"
}, {
"name": "Margalo"
}, {
"name": "Genevieve"
}, {
"name": "Niel"
}, {
"name": "Heddi"
}, {
"name": "Gregg"
}, {
"name": "Eduard"
}, {
"name": "Kizzee"
}, {
"name": "Truman"
}, {
"name": "Merill"
}, {
"name": "Lindie"
}, {
"name": "Vasily"
}, {
"name": "Averil"
}, {
"name": "Golda"
}, {
"name": "Zorine"
}, {
"name": "Odele"
}, {
"name": "Amalie"
}, {
"name": "Ilsa"
}, {
"name": "Pepillo"
}, {
"name": "Hewe"
}, {
"name": "Byrann"
}, {
"name": "Alford"
}, {
"name": "Lanny"
}, {
"name": "Kristina"
}, {
"name": "Mar"
}, {
"name": "Vittoria"
}, {
"name": "Winslow"
}, {
"name": "Ashlan"
}, {
"name": "Gayelord"
}])
const [searchTerm, setSearchTerm] = useState('')
const filteredName=names.filter((val)=>{
if(searchTerm ===""){
return val;
}else if(val.name.toLowerCase().includes(searchTerm.toLowerCase())){
return val;
}
});
const renderStatementResult = searchTerm && searchTerm.length > 0;
return (
<>
<div className="srchField">
<label for="statement">Statement Name</label>
<div className="valueField">
<input type="text" name="fileName" id="statement" data-validate="true" placeholder="Type Name" onChange={event => {setSearchTerm(event.target.value)}}/>
{
renderStatementResult ? <ul className="lookup-results">
{filteredName.map((value)=>(<li key={value.name}>{value.name}</li>))}
</ul> : null
}
</div>
</div>
</>
);
}
export default App;
refer this image
Can anyone have an idea of how to match the highlighted text. I want to highlight all s in yellow color
Replace your map function with
filteredName.map((value) => {
let string = value.name.substr(
0,
value.name.toLowerCase().indexOf(searchTerm.toLowerCase())
);
let endString = value.name.substr(
value.name.toLowerCase().indexOf(searchTerm.toLowerCase()) +
searchTerm.length
);
let highlightedText = value.name.substr(
value.name.toLowerCase().indexOf(searchTerm.toLowerCase()),
searchTerm.length
);
return (
<li key={value.name}>
{string}
<span style={{ "background-color": "#FFFF00" }}>
{highlightedText}
</span>
{endString}
</li>
);
})
The first line( let string =...) extracts the part of string which comes before the part that should be highlighted, and the next line extracts the part after the highlight. The search term itself is kept in a span tag which is styled to highlight.
The above snippet only highlights the first occurrence of the search term, so if the search term is 's' and one of the names is 'Samson', only the first 's' would be highlighted. If you want to highlight all occurrences, then you can use regular expressions to find out the indices of all occurrences and loop across the indices, constructing your li tag along the way.
A working sandbox can be found at https://codesandbox.io/embed/elated-chandrasekhar-ggoi1?fontsize=14&hidenavigation=1&theme=dark
Try this
{filteredName.map((value)=>(<li key={value.name}>{
value.name.split('').map((char) => {
if (searchTerm.toLowerCase().split('').includes(char.toLowerCase())) {
return <span style={{ color: 'yellow' }}>{char}</span>;
} else {
return <span>{char}</span>;
}
})
}</li>))}

How to search and filter in array of objects on setState

I'm trying to create a search based on an array of objects with react which data is in this format:
const data = [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
},
{
"name": "Mango Sticky Rice",
"desc": "Mango, rice, milk",
"allergens": ""
}
]
}
]
I stored this data inside useState declaration to be able to render accordingly on data chnage:
const [filteredBySearch, setFilteredBySearch] = useState(data)
I have an input where we can type anything and set inside useState declaration.
Goal:
If I type in my input:
"Jui"
Output should be:
console.log(filteredBySearch)
/* output:
[
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
},
{
"name": "Ananas",
"desc": "juice, ananas, water"
}
]
},
{"category 2" : []
}
]*/
Exemple 2:
If I type in my input:
"Orange banana"
Output should be:
console.log(filteredBySearch)
/* output: [
{"category 1" : [
{
"name": "Orange",
"desc": "juice, orange, Water"
}
]
},
{"category 2" : [
{
"name": "Banana Split",
"desc": "Banana, ice cream, chocolat, topping",
"allergens": "nuts"
}
]
}
]*/
I've try creating a new object with map and filter and set it with setFilteredBySearch, but I can't get anything, even creating this new object.
This the full component:
import Card from '../components/Card'
import React, { useState } from 'react';
export default function IndexPage({ data, search }) {
//search is the result of input value set on a useState
//Filter categoriesFoods by search
const [FilteredBySearch, setFilteredBySearch] = useState(data)
return (
<div className="main-content">
<div className="card-container">
{
FilteredBySearch.map(function(el, i) {
return (
<div key={i}>
<h2 className="category" id={Object.keys(el)}>{Object.keys(el)}</h2>
{
el[Object.keys(el)].map (function(itm,index){
return <Card key={index} infoItem={itm}/>
})
}
</div>
)
})
}
</div>
<style jsx>{`...`}</style>
</div>
)}
Any idea for me ?
Thanks a lot for your guidance!
I think this is what you are looking for. I have created below utilities for filtering as per your requirement.
const dataObj = [
{
'category 1': [
{
name: 'Orange',
desc: 'juice, orange, Water',
},
{
name: 'Ananas',
desc: 'juice, ananas, water',
},
],
},
{
'category 2': [
{
name: 'Banana Split',
desc: 'Banana, ice cream, chocolat, topping',
allergens: 'nuts',
},
{
name: 'Mango Sticky Rice',
desc: 'Mango, rice, milk',
allergens: '',
},
],
},
]
const checkIfInputMatches = (input, desc) => input.toLowerCase().split(" ").some(o => desc.toLowerCase().includes(o))
const filterByInput = (data, input) => {
let finalResult = [];
data.forEach(d => {
let keys = Object.keys(d);
let values = Object.values(d);
finalResult = [...finalResult, ...values.map((obj, index) => {
let result = obj.filter(o => checkIfInputMatches(input, o.desc))
return {[keys[index]]: result}
})]
})
return finalResult
}
console.log(filterByInput(dataObj, 'JUI'))
console.log(filterByInput(dataObj, "orange"))
console.log(filterByInput(dataObj, "rice"))
console.log(filterByInput(dataObj, "Orange banana"))
Hope this helps.

Rendering a nested object state

This problem is giving me a huge headache so any help is welcome :)
In this component, I'm making 2 axios calls to different APIs: one for freegeoip and one for openweathermap. I'm storing the data in the currentCity state, which is an object with 2 keys, location and weather. The idea is that the app detects your current location (using freegeoip) and renders location name and weather data (using openweathermap).
I'm positive it's storing the state properly as console logs have confirmed. I can render the location data for currentCity state, but can't seem to render the weather data for currentCity state.
renderCurrentCity(city) {
console.log('state3:', this.state.currentCity);
console.log([city.weather.main]);
return(
<div>
<li>{city.location.city}, {city.location.country_name}</li> // Working
<li>{city.weather.main.temp}</li> // Not working
</div>
)
}
The console error I get:
Uncaught (in promise) TypeError: Cannot read property '_currentElement' of null
currentCity.location JSON:
{
"ip": // hidden,
"country_code": "FR",
"country_name": "France",
"region_code": "GES",
"region_name": "Grand-Est",
"city": "Reims",
"zip_code": "",
"time_zone": "Europe/Paris",
"latitude": 49.25,
"longitude": 4.0333,
"metro_code": 0
}
currentCity.weather JSON:
{
"coord": {
"lon": 4.03,
"lat": 49.25
},
"weather": [
{
"id": 800,
"main": "Clear",
"description": "clear sky",
"icon": "01d"
}
],
"base": "stations",
"main": {
"temp": 283.15,
"pressure": 1011,
"humidity": 43,
"temp_min": 283.15,
"temp_max": 283.15
},
"visibility": 10000,
"wind": {
"speed": 3.1,
"deg": 350
},
"clouds": {
"all": 0
},
"dt": 1493127000,
"sys": {
"type": 1,
"id": 5604,
"message": 0.1534,
"country": "FR",
"sunrise": 1493094714,
"sunset": 1493146351
},
"id": 2984114,
"name": "Reims",
"cod": 200
}
Rest of code:
import React, { Component } from 'react';
import axios from 'axios';
import WeatherList from './weatherlist';
import SearchBar from './searchbar';
const API_KEY = '95108d63b7f0cf597d80c6d17c8010e0';
const ROOT_URL = 'http://api.openweathermap.org/data/2.5/weather?'
export default class App extends Component {
constructor(props) {
super(props);
this.state = {
cities: [],
errors: '',
currentCity: {
location: {},
weather: {}
}
};
this.currentCity();
this.renderCurrentCity = this.renderCurrentCity.bind(this);
}
citySearch(city) {
const url = `${ROOT_URL}&appid=${API_KEY}&q=${city}`;
axios.get(url)
.then(response => {
const citiesArr = this.state.cities.slice();
this.setState({
cities: [response.data, ...citiesArr],
errors: null
});
})
.catch(error => {
this.setState({
errors: 'City not found'
})
})
}
currentCity() {
var city;
var country;
axios.get('http://freegeoip.net/json/')
.then(response => {
const lat = response.data.latitude;
const lon = response.data.longitude;
city = response.data.city;
country = response.data.country_name;
const url = `${ROOT_URL}&appid=${API_KEY}&lat=${lat}&lon=${lon}`;
const state = this.state.currentCity;
console.log('state1:',state);
this.setState({
currentCity: { ...state, location: response.data }
});
console.log(url);
axios.get(url)
.then(city => {
const state = this.state.currentCity;
console.log('state2:', state);
this.setState({
currentCity: { ...state, weather: city.data }
});
})
})
}
renderCurrentCity(city) {
console.log('state3:', this.state.currentCity);
console.log([city.weather.main]);
return(
<div>
<li>{city.location.city}, {city.location.country_name}</li>
<li>{city.weather.main.temp}</li>
</div>
)
}
render() {
return (
<div className={this.state.cities == false ? 'search': 'search-up'}>
<h1>What's the weather today?</h1>
<ul className='list-unstyled text-center'>
{this.renderCurrentCity(this.state.currentCity)}
</ul>
<SearchBar
onSearchSubmit={this.citySearch.bind(this)}
errors={this.state.errors} />
{this.state.cities == false ? null : <WeatherList cities={this.state.cities} />}
</div>
)
}
}
You are spreading your whole state when your receive the weather data:
this.setState({
currentCity: { ...state, weather: city.data }
});
it should be:
this.setState({
currentCity: { ...state.currentCity, weather: city.data }
});

Resources