My API is returning below result.
I have below code to display in list.
const [result,setResult] = useState([]);
const fetchStatus = async ()=>{
await httpClient.get( config.resourceServerUrl+"/certificates/status").then(res=>{
setResult(res.data);
setActive(true);
alert(result);
})
and I am displaying list like below.
<div className="col-md-4">
<label htmlFor="status">Status</label>
<select
name="requestStatus"
style={{ display: 'block' }}>
<option value="" selected >
Please Select the Status
</option>
{
active && result.map((sts:any)=>{
<option key="" value="">
{sts}
</option>
})
}
</select>
though there is no error but it is not displaying anything.
Its because you've got {} around your JSX, should be ()
active && result.map((sts:any) => (
<option>{sts}</option>
))
or you can do
active && result.map((sts:any) => {
return (
<option>{sts}</option>
)
})
I don't believe you await httpClient.get. The .then will be called when the get completes.
you are setting the dropdown to each object in the returned array. You want to set it to the value of the request_status key: sts.request_status
set the key attribute for elements you create using map
{
active && result.map((sts:any)=>{
{sts.request_status}
})
}
Related
I am using React. I am trying to get a featured image from a list of files that the user has selected. I am trying to make the user select a number which corresponds to an image file. I have the following:
const handleFeatureImageChange = (event) => {
setFeatureImage(event.target.value);
console.log(event.target.value);
};
return(
{selectedFiles.length > 0 && (
<div>
<select name="is_feature" onChange={handleFeatureImageChange}>
{selectedFiles.map((selectedFile, index) => {
return (
<option key={index} value={selectedFile}>
{index + 1}{console.log(selectedFile)}
</option>
);
})}
</select>
</div>
)}
);
But console.log(event.target.value) inside the handleFeatureImageChange function prints [object File] as a string. But I want the actual file object there. console.log(selectedFile) inside the jsx prints the actual file object. How can I get the file object in the handleFeatureImageChange function ?
I'm trying to make this app, it's a simple react app with google books API. My question is how can I filter rendered elements depending on select value? I've tried useEffect and .filter method but I just can't figure it out. Here's what I got so far:
function App() {
const[book, setBook] = useState("");
const[result, setResult] = useState([]);
const[apiKey, setApiKey] = useState("MY API KEY");
const[sortBy, setSortBy]= useState("relevance")
const [categorie, SetCategorie]= useState("all")
function handleChange(event){
const book = event.target.value;
setBook(book)
};
function handleSubmit(event){
event.preventDefault()
axios.get("https://www.googleapis.com/books/v1/volumes?q="+book+"&key="+apiKey+"&maxResults=30&orderBy="+sortBy)
.then(function(res){
setResult(res.data.items)
console.log(res.data.items)
})
};
And that's when the problem starts
useEffect(function(){
result.filter(function(book){
const filteredBooks =
book.volumeInfo.categories.includes(categorie)
console.log(book)
})
},[categorie])
return (
<div className="container mt-4 ">
<h1>Search for books API</h1>
<form onSubmit={handleSubmit}>
<div className="form-group ">
<input onChange={handleChange}
type="text" className="form-control "
autoComplete="off"
placeholder="enter book name">
</input>
</div>
<button type="submit" className="btn btn-success"> Search now</button>
<select onChange={function(event){
let selectedSortBy = event.target.value;
setSortBy(selectedSortBy)
}}>
I've also needed to change API requests with select values, but that bit seems to work fine
<option value="relevance">Relevance</option>
<option value="newest">Newest</option>
</select>
</form>
<select onChange = {function(event){
let selectedCategorie = event.target.value;
SetCategorie(selectedCategorie);
}}>
<option value="all">All</option>
<option value="Art">Art</option>
<option value="Biography">Biography</option>
<option value="Computers">Computers</option>
<option value="History">History</option>
<option value="Medical">Medical</option>
<option value="Poetry">Poetry</option>
</select>
<div class="row">
{result.map(book => {
return <div class="col">
<div class="box">
<Card
img = {book.volumeInfo.imageLinks === undefined
? ""
: `${book.volumeInfo.imageLinks.thumbnail}`}
category = {book.volumeInfo.categories}
title = {book.volumeInfo.title}
authors = {book.volumeInfo.authors}
/>
</div>
</div>
})}
</div>
</div>
);
}
export default App;
As I understand, you have select component which contains book categories list and once user changes the category you wish to show books only with selected categories.
const onCategoryChange = (event) => {
const selectedCategory = event.target.value;
const filteredBooks = result.filter((book) =>
book.volumeInfo.categories.includes(selectedCategory));
setCategories(selectedCategory);
setResult(filteredBooks);
};
<select onChange = {onCategoryChange}>
Get all categories
Filter out the books using the categories
Set categories and books.
Im not too familiar with react hooks, however if I understand correctly the function runs every time the category variable changes. The filter method needs to return truish value if you want to keep an item and falseish if not. It creates a new array which is returned. In your case you only set a const and log a value, returning void (implicit).
This should update the result to match your filtered books.
useEffect(function(){
result = result.filter(function(book){
const includesCategory = book
.volumeInfo
.categories
.includes(categorie);
console.log(book)
return includesCategory;
})
},[categorie])
I'm working on a React App. I have multiple select tags and different options to display and I wrote a function that receives the options and returns the whole select tag. I call this function multiple times from the render() method. I wanted to reuse the code. For some reasons the select options and not showing.
My code is something like that:
DisplayMenu = (id, options) => {
let menu = <div className="model"> Model
<select id={id}>
{
this.options.map( (item, index) => {
<option value={index}>{item}</option>
})
}
</select>
</div>
return menu;
}
render(){
return (
<div id="main">
// other <p> elements here
<Collapsible trigger="Actors">
{this.DisplayMenu("FirstActor", this.props.Details["FirstActor"])}
{this.props.Details["OtherActors"].map ( ( item, index) =>
this.DisplayMenu("OtherActor" + index, item)
)}
</Collapsible>
//oher <button> tags here
</div>
)
}
The functions displays the select tag but options are empty. My arrays are good, I checked the values. I assumed that the cause may be the z-index value for the tag, I tried to chage it but again nothing is displayed. Also in the browser console this is displayed:
<select id="FristActor model "></select> ==$0
Any ideas will help. Thank you.
You're not returning from your map function
<select id={id}>
{
this.options.map( (item, index) => {
return <option value={index}>{item}</option>
})
}
</select>
Sorry i'm not able to comment due to less reputation.
Updating Kumar's answer if you not want to write return.
<select id={id}>
{
this.options.map( (item, index) => (
<option value={index}>{item}</option>
))
}
</select>
Thanks.
I am trying to render a simple drop down with numbers from 1 to 100. I create an object with an array as its only element. I populate each array element with a value and then I try to map the object to generate the drop down items. This is the code I am executing:
renderPercent = () => {
let obj = {
array: []
};
for (var l=0;l<100;l++){
obj.array[l] = l+1;
}
console.log("obj: ", obj);
let optionItems = obj.array.map((item) =>
<option key={item}>{item}</option>
);
return (
<div>
<div className="row">
<div className="col-9 text-left">
<label>Select the percent to transfer</label>
</div>
<div className="col-2 text-left">
<select>
{optionItems}
</select>
</div>
<div className="col-1 text-left">
<label> </label>
</div>
</div>
</div>
)
}
I modified the optionItems map function as suggested. This is what now is generated when this screen is rendered:
As you can see, the map function is now populating my drop down. However, the dropdown goes below the end of the device. Is this just something that is a bug when viewing in Chrome with developer tools? And the other thing I noticed is that the numbers in the dropdown are a larger font than the reset of the page. Before I click on the dropdown arrow, the value 1 shows in the drowdown and that is the correct size, but as soon as I expand the drop down, the numbers seem much larger. Why would that be?
Again, thanks to the stackoverflow community!
obj is an object, it doesn't have a map function. Whereas obj.array is a list that have a map function.
The following code
let optionItems = obj.map((item) =>
<option key={item.array}>{item.array}</option>
);
should be
let optionItems = obj.array.map((item) =>
<option key={item}>{item}</option>
);
You are trying to map on an object, not an array, modify your code as so:
obj.map((item) =>
should be
obj["array"].map((item) =>
You can see that in your console.log. It says { array: [....
You can do this.
{Array.from(Array(100), (e, i) => {
return <option value={i+1}>{i+1}</option>
}
)}
"i" will contain a value from 0 to 100 that's why I make it "i+1"
You are doing .map on object but not on array. Try with . notation
let optionItems = obj.array.map((item) =>
<option key={item.array}>{item.array}</option>
);
complete code
renderPercent = () => {
let obj = {
array: []
};
for (var l=0;l<100;l++){
obj.array[l] = l+1;
}
return (
<div>
<select>
{obj.array.length > 0 && obj.array.map((item) =>
<option key={item.array}>{item.array}</option>
)}
</select>
</div>
)
}
Try some like this:
var percentArray = [];
for (var l=0;l<100;l++){
percentArray.push(l);
}
let optionItems= percentArray.map(x => `<option key=${x}>${x}</option>`);
...
return (
<div>
<select>
{optionItems}
</select>
</div>
)
Use the defaultValue or value props on instead of setting selected on .
<select defaultValue="react">
<option value="react">React</option>
<option value="angular">Angular</option>
</select>
defaultValue would work with the above select tag. However, it does not seem to work with options generated by loop.
<select defaultValue={selectedOptionId}>
{option_id.map(id =>
<option key={id} value={id}>{options[id].name}</option>
)}
</select>
Probably options not fully been set when defaultValue was declared?
I could do manual assigning in componentDidUpdate() and onChange event.
But my question is - Is there any cleaner(better) way to solve it?
Thanks.
This is old, but since answer #1 is related to a controlled Select and the question seems to be related to uncontrolled Select I think is worth to leave some lines for future readers:
The problem is that for uncontrolled components React needs to know what are the options before the first render, since from that moment the defaultValue won't override the current value of the Select. This means that if you render the Select before the options it won't know what to select.
You can solve the problem avoiding the render before the options are available:
const RenderConditionally = ({ options, selected }) => options.length > 0 ? (
<select defaultValue={selected}>
{options.map(item => (
<option key={item.id} value={item.value}>{item.label}</option>
))}
</select>
) : null;
Or without ternary if you desire:
const RenderConditionally = ({ options, selected }) => {
if (options.length === 0) {
return null;
}
return (
<select defaultValue={selected}>
{options.map(item => (
<option key={item.id} value={item.value}>{item.label}</option>
))}
</select>
);
};
For users running into this issue, you can get the desired functionality by using the value prop, instead of defaultValue, e.g.:
<select value={selectedOptionId}>
{option_id.map(id =>
<option key={id} value={id}>{options[id].name}</option>
)}
</select>
Most probably you have something wrong with option_id and options arrays structure, or selectedOptionId variable. The way you build your select component is ok.
I've made a fiddle where this code works fine:
render: function() {
let option_id = [0, 1];
let options = [{name: 'a'}, {name: 'b'}];
let selectedOptionId = 1
return (
<select defaultValue={selectedOptionId}>
{option_id.map(id =>
<option key={id} value={id}>{options[id].name}</option>
)}
</select>
)
}
The best solution that I could find is to set key attribute the same as defaultValue so it will be a different element.
Aftermaths are not researched by me but I believe it should be okay.