Load dropdownlist data from api in reactjs - reactjs

I am new to react js and once again got stuck in an issue. I am trying to load a dropdown list from an api call. Although I am able to get data from API and save it to state, I am not able to use it to bind it to the dropdown list. Following is my code to fetch and bind the data:
const initialState = {
venues: []
};
export default class AddLab extends Component {
constructor() {
super();
this.state = initialState;
this.getVenueList();
this.handleChange = this.handleChange.bind(this);
}
getVenueList() {
ApiService.getData(apiConfig.GET_VENUES, {}).then((res) => {
if (res.data && res.data.error == null) {
this.state.venues = res.data.result;
console.log(this.state.venues);
} else {
alert(res.data.error.description );
}
});
}
render() {
return (
<div className="card col-md-4">
<Row>
<Col>
<Form.Label>Venue</Form.Label>
<Form.Control as="select" componentclass="select" placeholder="Select venue" onChange={this.handleVenueChange}>
<option value="select">Select venue</option>
{
this.state.venues.map((venue) => {
return (<option value="s">{venue.venueName}</option>);
})
}
{/* <option value={apiConfig.ROLE_ADMIN}>Admin</option> */}
{/* <option value={apiConfig.ROLE_CLIENT}>Client</option> */}
</Form.Control>
<div style={{ fontSize: 12, color: "red" }}>
{this.state.projectIdError}
</div>
</Col>
</Row>
{this.state.isLoading ? (<div style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
height: '100vh'
}}><div className="spinner-border text-primary" role="status" >
<span className="sr-only">Loading...</span>
</div></div>) : (<div></div>
)}
<div style={divStyle}>
<Button type="submit" name="submit" className="btn btn-primary mb-2">
Submit
</Button>
</div>
</div>
</Form>
</div>
);
}
}
I am able to get data from api in my getVenueList method but even when setting it to state, the dropdown list is not updated.

You are not updating the state correctly, in your getVenue method set state as following:
this.setState({
venues: res.data.result
});

Related

Create dynamic json based on user input

I have two dropdowns and a couple of images on it what I want is when the user selects the dropdowns and selects image I want to create the JSON format like below:
[data: {
dropdown1:'user input',
dropdown2:'user input',
image url:'url'
}]
my react code:
import React from "react";
import axios from 'axios'
import '../Login.css'
export default class Inference extends React.Component {
constructor(props) {
super(props);
this.state = {
courses: [],
course: "",
inferenceout: [],
model: "",
isLoading: false,
options: [
{ label: "resnet-50torch", value: "resnet-50torch" },
{ label: "densenet_onnx", value: "densenet_onnx" },
{ label: "inception_graphdef", value: "inception_graphdef" },
],
};
this.handleChange = this.handleChange.bind(this);
this.handleChangeCourse = this.handleChangeCourse.bind(this);
this.click = this.click.bind(this);
}
handleChange(e) {
console.log("Model Selected!!");
this.setState({ model: e.target.value });
}
handleChangeCourse = (event) => {
this.setState({ course: event.target.value });
};
getUnique(arr, comp) {
const unique = arr
//store the comparison values in array
.map((e) => e[comp])
// store the keys of the unique objects
.map((e, i, final) => final.indexOf(e) === i && i)
// eliminate the dead keys & store unique objects
.filter((e) => arr[e])
.map((e) => arr[e]);
return unique;
}
click() {
this.setState({ isLoading: true });
axios
.get(
`http://localhost:5000/model-list`
)
.then((res) => {
this.setState({
inferenceout: res.data , isLoading: false,
})
let newWin = window.open("about:blank", "res.data", "width=400,height=400");
newWin.document.write(JSON.stringify(res.data))
localStorage.setItem("apiData", JSON.stringify(res.data));
var data = JSON.parse(localStorage.getItem("apiData"));
console.log(data)
})
}
handleSubmit(event) {
event.preventDefault();
axios.post('http://localhost:5000/getmodel', {
model: this.state.model,
dataset:this.state.course
})
.then((res) => {
// Res.data is the response from your server
localStorage.setItem("apiData1", JSON.stringify(res.data));
});
var data = JSON.parse(localStorage.getItem("apiData1"));
console.log(data)
}
componentDidMount() {
axios
.get(`http://localhost:5000/files`)
.then((response) =>
this.setState(
{
courses: response.data
},
)
)
.catch((err) => console.log(err))
}
render() {
const uniqueCouse = this.getUnique(this.state.courses, "dataset");
const { courses, course, options } = this.state;
const filterDropdown = courses.filter(function (result) {
return result.dataset === course;
});
return (
<div className="container">
<div className="row">
<div
className="col-6"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}
>
<label
className=""
style={{ paddingTop: "5px", marginTop: "40px" }}
>
Dataset
<form onSubmit={this.handleSubmit.bind(this)}>
<select
className="custom-select"
value={this.state.course}
onChange={this.handleChangeCourse}
style={{ paddingTop: "5px", marginTop: "10px" }}
>
<option>--Select--</option>
{uniqueCouse.map((course) => (
<option key={course.id} value={course.dataset}
onChange={(e) => this.setState({ dataset: e.target.value })}>
{course.dataset}
</option>
))}
</select>
<button
type="submit"
class="btn"
style={{ marginTop: "" }}
>
ok
</button>
</form>
</label>
</div>
<div
className="col-6"
style={{
paddingBottom: "100px",
paddingTop: "20px",
alignItems: "center",
}}
>
<label
className=""
style={{ paddingTop: "5px", marginTop: "40px" }}
>
Model
<form onSubmit={this.handleSubmit.bind(this)}>
<select
className="custom-select"
name="example"
value={this.state.model}
onChange={this.handleChange}
style={{ paddingTop: "5px", marginTop: "10px" }}
>
<option>--Select--</option>
{options.map((option) => (
<option
value={option.value}
onChange={(e) => this.setState({ model: e.target.value })}
>
{option.label}
</option>
))}
</select>
<button
type="submit"
class="btn"
style={{ marginTop: "" }}
>
ok
</button>
</form>
</label>
</div>
{filterDropdown.map((course) => (
<div className="col-2">
<input type="checkbox" id="myCheckbox1" />
<label for="myCheckbox1" className="labell">
<img
key={course.id}
src={`${course.path}`}
height="80"
className="card-img-top img-responsive"
alt="img"
/>
</label>
</div>
))}
<button
type="submit" onClick={this.click} disabled={this.state.isLoading}
class="btn btn-success"
style={{ marginLeft:"45%" ,marginBottom:"10px"}}
>
Inference
</button>
<button
type="submit"
class="btn btn-primary"
style={{ marginLeft:"45%"}} onClick={()=> window.open("/visual", "data","width=400,height=400")}
>
Get Output
</button>
</div>
</div>
);
}
}
the dropdown data are coming from nodejs and images from nodejs also. i want to get the user input as a JSON. i couldn't able to do that thats why i'm asking here kindly help me
please guide me on how to do that

MUI Icon button show border when clicked

I have used an Iconbutton for my website but when it is clicked it shows a border & the animation is also gone. Also, I would like to know how to assign functions to my + / - buttons to increase & decrease the value in the text input. following is my full code. I get the NaN in
Code:
export class BookingSummary extends Component {
constructor(props) {
super(props);
this.state = {
seatPrice: [],
dataLoaded: false,
priceList :[],
};
}
state = { value: 0 };
onPlusClick = () => {
this.setState({ ...this.state, value: this.state.value + 1 });
};
onMinusClick = () => {
this.setState({ ...this.state, value: this.state.value - 1 });
};
render () {
return (
<IconButton
onClick={this.onMinusClick}
aria-label="minus"
style={{ marginTop: 15 }}
>
<RemoveCircleIcon fontSize="inherit" />
</IconButton>
<TextField
value={this.state.value}
id="outlined-adornment-small"
// defaultValue="50"
variant="outlined"
size="small"
style={{ width: 48, height: 35 }}
labelWidth={0}
/>
<IconButton
onClick={this.onPlusClick}
aria-label="plus"
style={{ marginTop: 15 }}
>
<AddCircleIcon fontSize="inherit" />
</IconButton>
You can achieve your aim with predifined setState in classify component. Also you need to use onClick for IconButtons. When user clicks on the buttons, you should change the value of the counter. Here's the classify component which you would like to implement:
import React from "react";
import IconButton from "#material-ui/core/IconButton";
import TextField from "#material-ui/core/TextField";
import RemoveCircleIcon from "#material-ui/icons/RemoveCircle";
import AddCircleIcon from "#material-ui/icons/AddCircle";
import "./styles.css";
export class MyComponent extends React.Component {
state = {
value: 0
};
onPlusClick = () => {
this.setState({ ...this.state, value: this.state.value + 1 });
};
onMinusClick = () => {
this.setState({ ...this.state, value: this.state.value - 1 });
};
render() {
return (
<div className="App">
<div className="col-xl-4 col-lg-4 col-md-12 col-sm-12 col-12">
<div className="row">
<div className="col-md-12">
<div className="st_dtts_bs_wrapper float_left">
<div className="st_dtts_bs_heading float_left">
<p>Booking summary</p>
</div>
<div className="st_dtts_sb_ul float_left">
<ul>
<li>
movieData.seats
<br />( 5 Tickets ) ODC <span>Rs .50</span>
</li>
<li>
Child Tickets
<br />( 2 Tickets ) ODC <span>Rs .5 </span>
<br />
<br />
<IconButton
onClick={this.onMinusClick}
aria-label="minus"
style={{ marginTop: 15 }}
>
<RemoveCircleIcon fontSize="inherit" />
</IconButton>
<TextField
value={this.state.value}
id="outlined-adornment-small"
defaultValue="50"
variant="outlined"
size="small"
style={{ width: 48, height: 35 }}
labelWidth={0}
/>
<IconButton
onClick={this.onPlusClick}
aria-label="plus"
style={{ marginTop: 15 }}
>
<AddCircleIcon fontSize="inherit" />
</IconButton>
</li>
<li>
Handling fees <span>Rs. 25</span>
</li>
</ul>
</div>
<div className="st_dtts_sb_h2 float_left">
<h3>
Sub total <span>Rs. 55</span>
</h3>
<h4>
Current State is <span>Colombo</span>
</h4>
<h5>
Payable Amount{" "}
<span style={{ color: "#ff4444" }}>Rs. 555</span>
</h5>
</div>
</div>
</div>
</div>
</div>
</div>
);
}
}
export default function App() {
return <MyComponent />;
}

How to concatenate URL and string, and get data from API at click a button using axios in REACT JS

this is my code:
import React, { Component } from 'react'
import { Button, Form, Card, Table } from 'react-bootstrap';
import { Link } from 'react-router-dom';
import axios from 'axios';
class Ceklaporan extends Component {
constructor(props) {
super(props);
this.state = {
client: "10018318318anhsajda0skflisjf",
uniq_id: '',
data: [],
}
}
notiket() {
axios({
method: 'GET',
url: 'http://11100011000/bla/?m=api&f=jadjsjf&client_id=djhajdhajdhajc&uniq_id=${this.state.uniq_id}'
})
.then((v) => {
console.log(v.data)
})
.catch((e) => console.log(e.response))
}
render() {
return (
<div className='container'>
<div className="row justify-content-center">
<Form style={{ marginTop: 50, width: '40%' }}>
<Form.Group id="uniqid">
<Form.Control type="text"
placeholder=" Nomor Tiket Laporan"
name="uniqid"
onChange={(v) => this.setState({
uniq_id: v.target.value,
})}
value={this.state.uniq_id}
required />
</Form.Group>
<Button
variant="primary"
size="sm"
onClick={() => this.notiket()}
style={{
marginTop: 10,
marginBottom: 30,
width: '30%'
}}
>Simpan
</Button>
</Form>
</div>
<div className="container">
<Table striped bordered hover variant="light" style={{ marginTop: 20 }}>
<thead>
<tr>
<th>Nomor Tiket</th>
<th>Tanggal</th>
<th>Pengirim</th>
<th>Judul</th>
<th>Detail</th>
<th>Topik</th>
<th>Lokasi</th>
</tr>
</thead>
<tbody>
{this.state.data.map(data => (
<tr key={data.uniq_id}>
<td>{data.uniq_id}</td>
</tr>
))}
</tbody>
</Table>
</div>
<div className="card" >
<Card id="tindaklanjut">
<Card.Header as="h5" style={{ backgroundColor: '#0CCDA3', fontSize: 21, fontFamily: 'serif', color: 'white' }}>Detail Tindak Lanjut</Card.Header>
<Card.Body>
<div>
{this.state.data.map(data => (
<tr key={data.uniq_id}>
<td>{data.history}</td>
</tr>
))}
</div>
</Card.Body>
</Card>
</div>
</div>
)
}
}
export default Ceklaporan;
so when the user enters the complaint number previously obtained, when the "SEARCH" button is clicked, the "GET DATA" request from AXIOS to the API will appear in the table provided under the form, while for "FOLLOW-UP DETAIL" will appear on the card below it, the Card is specifically for displaying the "HISTORY" of the report
so my problem is:
1. concatenate URL and UNIQ_ID from the state that is in the function "NOTICET"
2. data cannot be displayed in the table below the form
3. HISTORY cannot be displayed on the card at the bottom of the table
This is the form to input the complaint number:
<!-- begin snippet: js hide: false console: true babel: false -->
This is the form to input the complaint number:
<div className="row justify-content-center">
<Form style={{ marginTop: 50, width: '40%' }}>
<Form.Group id="uniqid">
<Form.Control type="text"
placeholder=" Nomor Tiket Laporan"
name="uniqid"
onChange={(v) => this.setState({
uniq_id: v.target.value,
})}
value={this.state.uniq_id}
required />
</Form.Group>
<Button
variant="primary"
size="sm"
onClick={() => this.notiket()}
style={{
marginTop: 10,
marginBottom: 30,
width: '30%'
}}
>Simpan
</Button>
</Form>
</div>

Pass props to child component from parent component dynamically

I have a child component StepperNotification which gets an input from user and returns it as prop to its child component in following way.
const styles = {
transparentBar: {
backgroundColor: 'transparent !important',
boxShadow: 'none',
paddingTop: '25px',
color: '#FFFFFF'
}
};
const useStyles = makeStyles((theme: Theme) =>
createStyles({
formControl: {
margin: theme.spacing(1),
minWidth: 120,
},
selectEmpty: {
marginTop: theme.spacing(2),
},
}),
);
function getSteps() {
return ['Create', 'Audience', 'Timing'];
}
function getStepContent(step, $this) {
switch (step) {
case 0:
return (
<div className="row">
<CardBox styleName="col-lg-12"
heading="">
<form className="row" noValidate autoComplete="off" style={{"flex-wrap":"no-wrap", "flex-direction": "column" }}>
<div className="col-md-12 col-12">
<TextField
id="campaign_name"
label="Campaign Name"
value={$this.state.name}
onChange={$this.handleChange('name')}
margin="normal"
fullWidth
/>
</div>
</form>
</CardBox>
</div>
);
default:
return 'Unknown step';
}
}
class NotificationStepper extends React.Component {
state = {
activeStep: 0,
name: '',
};
handleChange = name => event => {
this.setState({
[name]: event.target.value,
});
this.props.titlechange(event.target.value);
};
handleNext = () => {
this.setState({
activeStep: this.state.activeStep + 1,
});
};
handleBack = () => {
this.setState({
activeStep: this.state.activeStep - 1,
});
};
handleReset = () => {
this.setState({
activeStep: 0,
});
};
render() {
const steps = getSteps();
const {activeStep} = this.state;
return (
<div className="col-xl-12 col-lg-12 col-md-7 col-12">
<Stepper className="MuiPaper-root-custom" activeStep={activeStep} orientation="vertical">
{steps.map((label, index) => {
return (
<Step key={label}>
<StepLabel>{label}</StepLabel>
<StepContent className="pb-3">
<Typography>{getStepContent(index, this)}</Typography>
<div className="mt-2">
<div>
<Button
disabled={activeStep === 0}
onClick={this.handleBack}
className="jr-btn"
>
Back
</Button>
<Button
variant="contained"
color="primary"
onClick={this.handleNext}
className="jr-btn"
>
{activeStep === steps.length - 1 ? 'Finish' : 'Next'}
</Button>
</div>
</div>
</StepContent>
</Step>
);
})}
</Stepper>
{activeStep === steps.length && (
<Paper square elevation={0} className="p-2">
<Typography>All steps completed - you"re finished</Typography>
<Button onClick={this.handleReset} className="jr-btn">
Reset
</Button>
</Paper>
)}
</div>
);
}
}
export default NotificationStepper;
In my parent component i am getting this prop value and passing it to another child component Tabcomponent in following way
ParentCompoennt.js
const SendNotification = ({match}) => {
let titlename = '';
let message = '';
function handleTitle(title_) {
console.log('in here');
console.log(title_);
titlename = title_;
}
return (
<div className="dashboard animated slideInUpTiny animation-duration-3">
<ContainerHeader match={match} title={<IntlMessages id="sidebar.notification"/>}/>
<div className="row" style={{'flex-wrap': 'no wrap', "flex-direction": 'row'}}>
<div className="col-xl-7 col-lg-7 col-md-7 col-7">
<NotificationStepper titlechange={handleTitle} />
<div className='flex-class' style={{'width': '100%'}}>
<Button color="primary" style={{"align-self": "flex-end", "border" : "1px solid", "margin-left": "10px", "margin-bottom": "40px"}} size="small" className="col-md-2 col-2">Fetch</Button>
<Button color="primary" style={{"align-self": "flex-end", "border" : "1px solid", "margin-left": "10px", "margin-bottom": "40px"}} size="small" className="col-md-2 col-2" color="primary">Discard</Button>
</div>
</div>
<div className="col-xl-5 col-lg-5 col-md-5 col-5" style={{"padding-top": "20px"}}>
<span style={{"margin-left" : "20px", "font-weight": "bold"}}>Preview</span>
<TabComponent {...{[title]:titlename}} message={message} />
</div>
</div>
</div>
);
};
export default SendNotification;
and in TabComponent i am getting this prop value and using it component in following way
TabContainer.propTypes = {
children: PropTypes.node.isRequired,
dir: PropTypes.string.isRequired,
};
class TabComponent extends Component {
state = {
value: 0,
};
render() {
const {theme} = this.props;
const title = this.props.title;
return (
<div className="col-xl-12 col-lg-12 col-md-12 col-12" style={{"margin-top": "15px"}}>
<NotifCard key={0} data={{'name': title, 'company': 'sayge.ai', 'image': require("assets/images/bell.png"), 'description': this.props.message}} styleName="card shadow "/>
</div>
);
}
}
TabComponent.propTypes = {
theme: PropTypes.object.isRequired,
};
export default withStyles(null, {withTheme: true})(TabComponent);
StepperNotification is working fine and props are being updated in parent. i have checked this by printing the updated values in console, but the props in TabComponent are not being updated. What am i doing wrong here? any help is appreciated.
Probaly this is your issue
<TabComponent {...{[title]:titlename}} message={message} />` this could be just
title is undefined and you are sending props[undefined]=titlename
Just do this
<TabComponent title={titlename} message={message} />`
And if SendNotification is react fuction component useState for keeping track of current titlename. If it still doesn't work after first fix this second will be another source of your problems.

Button/dropdown button disabled by default without specifying disabled

I am trying to add a dropdown button in my react project and its rendering as disabled by default. why is this happening ?
The first dropdown is working fine, i called the same dropdown in the navbar after this one and it renders as disabled. I tried other things as well, like adding a button also would not work for me.
The navbar is diplayed when i get a response from the backend and a different component is rendered (ResultTable)
import React from "react";
import ResultTable from "./ResultTable";
...
import DropdownButton from "react-bootstrap/DropdownButton";
import Dropdown from "react-bootstrap/Dropdown";
class MainContainer extends React.Component {
constructor(props) {
super(props);
this.state = {
//more state values
threshold: 0.75
};
this.thresholdChange = this.thresholdChange.bind(this);
}
thresholdChange(input) {
this.setState({
threshold: input
});
}
toProperCase = function (txt) {
return txt.replace(/\w\S*/g, function (txt) { return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase(); });
};
render() {
const { responseData } = this.state;
return (
<div className="container-flex container-without-scroll wrapper"
style={{
backgroundImage: `url(${bg})`,
width: "100%",
height: "100vh",
backgroundSize: "cover",
backgroundRepeat: "no-repeat",
overFlow:'hidden'
}}
>
<div
className={`container-fluid `}>
{this.state.displayTable ? (
<Navbar
style={{
position: "fixed",
left: "50%",
top: "95%",
transform: "translate(-50%, -90%)",
backgroundColor: 'black'
}}
sticky="bottom"
>
<br />
<Navbar.Collapse className="justify-content-end">
<Button
variant="primary"
disabled={
this.props.initialTransaction &&
this.props.initialTransaction.version == 0 &&
this.props.initialTransaction
? true
: false
}
size="sm"
style={{ color: "#FFF" }}
onClick={this.undoAction}
>
<span className=" fa fa-undo "></span>
Undo
</Button>
<Button
variant="primary"
size="sm"
style={{ color: "#FFF" }}
disabled={
(this.props.initialTransaction &&
this.props.initialTransaction.version) <
(this.props.currentVersion &&
this.props.currentVersion.version)
? false
: true
}
onClick={this.redoAction}
>
<span className=" fa fa-repeat "></span>
Redo
</Button>
<Button
variant="success"
size="sm"
style={{ color: "#FFF" }}
disabled={
this.props.initialTransaction &&
this.props.initialTransaction.version == 0
? true
: false
}
onClick={() =>
this.exportExcel(this.props.initialTransaction)
}
>
<span className=" fa fa-download "></span>
Export
</Button>
<DropdownButton
size="md"
title={this.state.threshold}
>
{this.state.thresholdValues.map(eachValue => {
return (
<Dropdown.Item
key = {Math.random()}
onClick={() => this.thresholdChange(eachValue)}
as="button"
>
{eachValue}
</Dropdown.Item>
);
})}
</DropdownButton>
</Navbar.Collapse>
<br/>
</Navbar>
) : null}
{this.state.displayTable ? null : (
<div
className="col-md-4 col-md-offset-4"
style={{
position: "absolute",
left: "50%",
top: "50%",
transform: "translate(-50%, -50%)",
backgroundColor: 'rgba(14, 13, 13, 0.74)'
}}
>
<br />
<div className="row">
<div className="input-group col-md-9">
<div className="input-group-prepend">
<span
style={{ cursor: 'pointer' }}
onClick={this.onFormSubmit}
className="input-group-text"
id="inputGroupFileAddon01"
>
{" "}
Upload{" "}
</span>
</div>
<div className="custom-file">
<input
type="file"
className="custom-file-input"
id="inputGroupFile01"
onChange={this.onChange}
aria-describedby="inputGroupFileAddon01"
/>
<label
className="custom-file-label"
htmlFor="inputGroupFile01"
>
{this.props.active && this.props.active.filename}
</label>
</div>
</div>
<div className="col-md-3">
<DropdownButton
size="md"
id="dropdown-item-button"
title={this.state.threshold}
>
{this.state.thresholdValues.map(eachValue => {
return (
<Dropdown.Item
onClick={() => this.thresholdChange(eachValue)}
as="button"
>
{eachValue}
</Dropdown.Item>
);
})}
</DropdownButton>
</div>
</div>
<br />
</div>
)}
<div >
{this.state.displayTable ? (
<div className = "container-flex" style =
{{overflowY:'scroll', maxHeight:'80vh'}}>
<ResultTable
data={responseData}
afterMerge={params => {
this.afterMerge(params);
}}
/>
</div>
) : null}
</div>
</div>
</div>
);
}
}
// Maps state from store to props
const mapStateToProps = (state, ownProps) => {
return {
};
};
// Maps actions to props
const mapDispatchToProps = dispatch => {
return {
};
};
// Use connect to put them together
export default connect(
mapStateToProps,
mapDispatchToProps
)(MainContainer);

Resources