Unable to update state on axios response in a class react js - reactjs

I'm unable to update the state using the axios response in a class component. It works just fine with function based components. Could somebody please point out what is causing this issue. I'm new to react and tried most of the possible answers out there.
code :
import React, { Component } from "react";
import "./Table.css";
import { Button } from "./Button";
import { Table } from "react-bootstrap";
import axios from "axios";
import Example from "./Progress";
class Tables extends Component {
constructor(props) {
super(props);
this.state = {
submitted: false,
task_id: "",
};
this.handlesubmit = this.handlesubmit.bind(this);
}
handlesubmit(event) {
var self = this;
event.preventDefault();
axios({
method: "post",
url: "http://127.0.0.1:8000/api/test/",
data: {
project_name: "test",
},
}).then(function (response) {
console.log(response.data.task_id); //prints taskid (12345678)
self.setState({
task_id: response.data.task_id,
});
console.log(self.task_id); //prints undefined
});
this.setState({ submitted: true }); //works fine, state is set to true
console.log(this.task_id); //prints undefined
}
render() {
let modal;
let task_id = this.state.task_id;
let submitted = this.state.submitted;
if (submitted === true) {
modal = <Example pro="test" task={task_id} />;
}
return (
<div className="table-div">
<Button
buttonStyle="btn--secondary"
buttonSize="btn--small--opt"
onClick={this.handlesubmit}
>
test
</Button>
{modal}
</div>
);
}
}
export default Tables;

You should update your state inside then when the axios call succeeds:
handleSubmit(event) {
event.preventDefault();
axios({...})
.then((response) => {
this.setState({
task_id: response.data.task_id,
submitted: true
})
})
.catch((error) => { /* handle errors appropriately */ })
}
Then, inside your render method, make sure that both task_id and submitted have appropriate values before rendering the modal:
render() {
const { task_id, submitted } = this.state
const modal = submitted && task_id !== ""
? <Example pro="test" task={task_id} />
: null // don't render anything
return (
<div className="table-id">
<Button ...>test</Button>
{modal}
</div>
)
}

Related

Display state.joke when toggle button is only ON

Im trying to make it so that the joke will display only when the toggle button is 'ON'. Right now I have the joke displaying all the time and not sure where I should go from here. Should I be using useEffect and how?
import React from 'react';
import axios from "axios";
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
this.jokes = "https://icanhazdadjoke.com/"
// This binding is necessary to make `this` work in the callback
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
async componentDidMount() {
const url = "https://icanhazdadjoke.com/"
let result = null;
try {
result = await axios.get(url, {
headers: {
Accept: "application/json"
}
})
} catch(e) {
console.log(e);
}
this.setState({jokes: result.data.joke});
}
render() {
return (
<div>
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
<p>
> This displays the joke and changes when page is refreashed
{this.state.jokes}
</p>
</div>
);
}
}
export default Toggle;
you can do it this way:
{this.state.isToggleOn && <p> {this.state.jokes} </p>
it only shows the joke when the toggle is on.

Why datatable cant show data in React JS (axios)

I use axios to create my datatatable using MUIDataTable in my React JS. but with my code the result is just show empty table..
in code below i dont know where i should change, because the result is empty table without data result as in JSON.why const data cant be read, anyone can help?
here's my code
App.js
import React,{Component} from "react";
import ReactDOM from "react-dom";
import MUIDataTable from "mui-datatables";
import axios from "axios";
import { Link } from 'react-router-dom';
class App extends Component {
// State will apply to the posts object which is set to loading by default
constructor(props) {
super(props);
this.state = {
data: [],
isLoading: true,
errors: null,
};
}
// Now we're going to make a request for data using axios
getData = async () => {
const option = {
url: "url/api",
method: 'POST',
data: {
"data": {
"name": "...",
"id":"..."
},
"encrypt": 0
}
};
axios(option)
.then(response => {
this.setState({
data: response.data.data,
isLoading: false,
});
console.log(response.data);
})
// If we catch any errors connecting, let's update accordingly
.catch(error => {
console.log(error.response);
this.setState({ error, isLoading: false })
}
);
}
// Let's our app know we're ready to render the data
componentDidMount() {
this.getData();
}
// Putting that data to use
render() {
const { isLoading, data } = this.state;
const columns = ["ID","Name];
const options = {
filterType: "dropdown",
responsive: "scroll",
selectableRows:false
};
return (
<div>
<center><h3>List Data</h3></center><br/>
<MUIDataTable
columns={columns}
options={options}
data={data}
/>
{!isLoading ? (
data.map(post => {
const {id, name} = post;
const data = [
[
{id},
{name}
})
) : (
<p>Loading...</p>
)}
</div>
);
}
}
ReactDOM.render(<App />, document.getElementById("root"));
export default App
Your option is wrong. url should be outside of the option. the correct order is:
axios.post('url' , options , headers).This may be helpful.For more info please visit https://github.com/axios/axios.

Trigger 2 re-renders on props change

I would like to the list of options to go back to empty on getting new a vesselname. Using the below code, updating optionList to an empty array inside componentDidUpdate does not trigger a re-render. So on selecting a new vessel, the previous keydate remains selected, although if I click the dropdown, I can see it is populated with new values from the api call.
KeydateDropdown.js
import React from 'react';
import Select from 'react-select';
import axios from 'axios';
class KeydateDropdown extends React.Component {
constructor(props) {
super(props);
this.state = {
optionList: []
};
};
componentDidUpdate(prevProps) {
let vesselname = this.props.vesselname;
if (prevProps.vesselname !== vesselname) {
let keydateList = [];
this.setState({
optionList: keydateList
});
axios.get('list-keydates', {
params: {
vesselname: vesselname
}
})
.then((response) => {
let data = response.data['intervention'];
data.forEach((element) => {
keydateList.push({ value: element, label: element });
});
this.setState({ optionList: keydateList });
})
}
}
render() {
return (
<Select
isDisabled={this.props.isDisabled}
onChange={this.props.handleKeydateChange}
options={this.state.optionList}
className={styles.dropdown}
/>
);
}
}
export default KeydateDropdown;
use
componentWillUpdate(nextProps)
or
componentDidUpdate(prevProps, prevState)

React + Laravel - Set State not defined

Iam trying to print back the value fetched from API. The data is coming but not able to set the state
Tried everything
React.js
import React, { Component } from 'react'
import axios from 'axios'
class Admin extends Component {
constructor(props) {
super(props)
this.state = {
users: []
}
}
componentDidMount(){
axios.get('/api/adminUsers')
.then(response =>{
this.setState({users: response.data})
console.log(response.data)
console.log(this.setState({users: response.data}))
})
.catch(error=>{
this.setState({ errorMsg: "Something is wrong here"})
console.log(error)
})
}
render() {
const{users} = this.state
<div>
{
users.length ?
users.map(user => <div key=
{user.id}>{user.name}</div>)
: null
}
</div>
)
}
}
export default Admin
The response.data showing in console is:
{[
created_at: "2019-08-31 14:06:29"
email: "amit.khare588#gmail.com5"
email_verified_at: null
id: 2
name: "Amit Khare"
role: "Doctor"
updated_at: "2019-08-31 14:06:29"
]}
I just want to print the data back
The code seems fine below is a fully working example:
import React from "react";
import ReactDOM from "react-dom";
class Admin extends React.Component {
constructor(props) {
super(props)
this.state = {
users: [],
errorMsg: ''
}
}
componentDidMount() {
axios.get('/api/adminUsers')
.then(response => {
this.setState({users: response.data.users})
console.log(response.data)
})
.catch(error => {
this.setState({errorMsg: "Something is wrong here"})
console.log(error)
})
}
render() {
const {users, errorMsg} = this.state;
return <div>
{users.length ? users.map(user => <div key={user.id}>{user.name}</div>) : null}
{errorMsg ? <div>{errorMsg}</div> : null}
</div>
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<Admin/>, rootElement);
Checkout the codesandbox: https://codesandbox.io/s/nice-fermi-ku1jr

fire onClick function from child component

TLDR: How would i retrieve the console.log from the child component
after url has been submitted
I want to be able to get the response data from the child component after a url has been submitted. How would i be able to do this ?
In other words how i be able to fire the onClick function after a url has been submitted ?
code sandbox
https://codesandbox.io/s/cool-feather-fjkv6
Parent
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import Child from './Child';
class Parent extends Component {
constructor(props){
super(props);
this.state = {
url:'',
outputUrl:''
}
}
onChange = (e) => {
e.preventDefault();
this.setState({
url: e.target.value
})
}
onSubmit = (e) => {
e.preventDefault();
console.log(this.state.url)
}
render(){
return (
<div className="App">
<form onSubmit={this.onSubmit}>
<input type="text" onChange={this.onChange} value={this.state.url} placeholder="Enter url " />
<button type="submit" >Submit</button>
</form>
{/* if have url else enter test url */}
<Child url={this.state.url} method={'GET'} />
</div>
);
}
}
export default App;
How would i retrieve the console.log from the child component after url has been submitted ? I'm slightly confused. Sorry if this is looks confusing.
Child
import React, {Component} from 'react';
import logo from './logo.svg';
import './App.css';
import axios from 'axios';
class Child extends Component {
constructor(props){
super(props);
this.state = {
data:[]
}
}
// componentDidUpdate or try this
onClick(){
const url = `${this.props.url}`;
if(this.props.method === "GET"){
axios.get(url).then( res => {
this.setState({
data: res.data
})
console.log(this.state.data)
})
}
else if(this.props.method === "POST"){
axios.get(url).then( res => {
this.setState({
data: res.data
})
console.log(this.state.data)
})
}
}
render(){
return (
null
);
}
}
export default Child;
Please! see render method on Child Component
class Child extends Component {
static onClick() {
// do something
}
constructor(props) {
super(props);
this.state = {
data: []
};
}
// componentDidUpdate or try this
onClick = e => {
e.preventDefault();
const url = `${this.props.url}`;
if (this.props.method === "GET") {
axios.get(url).then(res => {
this.setState({
data: res.data
});
console.log(this.state.data);
});
} else if (this.props.method === "POST") {
axios.get(url).then(res => {
this.setState({
data: res.data
});
console.log(this.state.data);
});
}
};
render() {
return <div onClick={this.onClick}>Click Me</div>;// <------
}
}

Resources