Home > Blockchain >  React Spring app issue - AxiosError Could not fetch properties. Object may no longer exist
React Spring app issue - AxiosError Could not fetch properties. Object may no longer exist

Time:12-09

I have a simple React Spring app. React part should take 3 parameters from frontend forms (city, state, country) after pressing Submit button, pass them to a backend Spring controller, get a response back and show data values from response on the same page. It works with hardcoded parameters, but there is an issue with more complex React logic.

Spring controller:

    @CrossOrigin
@RestController
@RequestMapping("/pollution")
public class PollutionController {
    private static final Logger LOGGER = Logger.getLogger(PollutionController.class.getName());

    JSONObject response;
    private final PollutionService pollutionService;

    PollutionController(PollutionService pollutionService) {
        this.pollutionService = pollutionService;
    }
    
    @GetMapping("/current/city")
    public JSONObject getCurrentPollutionDataByCityStateCountry(
            @RequestParam(value = "city") String city,
            @RequestParam(value = "state") String state,
            @RequestParam(value = "country") String country
    ) {
        try {
            response = pollutionService.getCurrentPollutionDataByCityStateCountry(city, state, country);
        } catch (Exception e) {
            e.printStackTrace();
        }
        LOGGER.log(Level.INFO, "/current/city response: {0}", response);
        return response;
    }

}

Response example:

{date=Thu Dec 08 01:15:37 CET 2022, no2=27.76, pm2_5=14.12, pm10=19.07}

React App.js part:

import React, { Component } from 'react'
import './App.css'

import axios from 'axios'

class App extends Component {

    constructor(props) {
        super(props)
        this.state = {
            responseData:'',
            date: '',
            no2: '',
            pm10: '',
            pm2_5: ''
        }

        this.handleClick = this.handleClick.bind(this)
    }

    handleClick () {
        const city = "New York";
        const state = "New York";
        const country = "US";

        axios.get('http://localhost:8080/pollution/current/city?'  
            'city='   city  
            '&state='  state  
            '&country='   country)
            .then(response => this.setState({responseData: response.data}))
        console.log("responseData.date: "   this.state.responseData.date);
    }

    render () {
        return (
            <div className='button__container'>
                <button className='button' onClick={this.handleClick}>Submit</button>
                <p> Date: {this.state.responseData.date}</p>
                <p> no2: {this.state.responseData.no2}</p>
                <p> pm10: {this.state.responseData.pm10}</p>
                <p> pm2_5: {this.state.responseData.pm2_5}</p>
            </div>
        )
    }
}
export default App

It works fine, I push Submit button, get response from backend and see results on the same webpage.

Simple valid result

But it is just a first test stage. As you see, all 3 input parameters are hardcoded here. So I added some logic in App.js file to take parameters from forms:

Updated App.js

import React, {Component} from 'react'
import './App.css'

import axios from 'axios'

class App extends Component {
    constructor(props) {
        super(props);
        this.state = {
            responseData:'',
            date: '',
            no2: '',
            pm10: '',
            pm2_5: '',
            city: '',
            state: '',
            country: '',
        };

        this.handleClick = this.handleClick.bind(this)
        this.handleInputChange = this.handleInputChange.bind(this);
    }

    handleInputChange(event) {
        const target = event.target;
        const value = target.value;
        const name = target.name;

        this.setState({
            [name]: value
        });
    }

    handleClick() {
    console.log("log record 1");
    console.log("city: "   this.state.city);
        axios.get('http://localhost:8080/pollution/current/city?'  
            'city='   this.state.city  
            '&state='  this.state.state  
            '&country='   this.state.country)
            .then(response => this.setState({responseData: response.data})).catch((err) => console.error(err));

    console.log("response data: "   this.state.responseData);
    console.log("log record 2");
    }

    render() {
        return (
            <form onSubmit={this.handleClick}>
                <label>City:
                    <input name="city" type="text" value={this.state.city} onChange={this.handleInputChange}/>
                </label>
                <br/>
                <label>State:
                    <input name="state" type="text" value={this.state.state} onChange={this.handleInputChange}/>
                </label>
                <br/>
                <label>Country:
                    <input name="country" type="text" value={this.state.country} onChange={this.handleInputChange} />
                </label>
                <br/>
                <input type="submit" value="Submit"/>
                <br/>
                <p> Date: {this.state.responseData.date}</p>
                <p> no2: {this.state.responseData.no2}</p>
                <p> pm10: {this.state.responseData.pm10}</p>
                <p> pm2_5: {this.state.responseData.pm2_5}</p>
            </form>
        );
    }
}
export default App

And here is an issue - I put values in the forms, push Submit, request is going to the backend part and it generates response (I can see from backend logs, that it gets parameters and produces a result json), but I don't see any results on the same webpage.

Backend response log:

INFO 77115 --- [nio-8080-exec-3] c.m.controller.PollutionController       : /current/city response: {"date":"Fri Dec 09 01:11:49 CET 2022","no2":"19.19","pm10":"45.54","pm2_5":"38.07"}

Result on a webpage:

No results

So my question(s) - what is wrong with added logic in updated App.js? Why it doesn't render the response data the same way as before? What I miss here?

UPDATE:

I've added some loggers in App.js (code above updated with them), and you can see the next result in console:

console screenshot

There is no data in console for console.log("response data: " this.state.responseData); and there are 2 errors after this. Why are these errors in my case?

UPDATE 2 :

I've added also exception handling (added to App.js above) and see this in console:

enter image description here

CodePudding user response:

Background: The default behavior of the forms is to refresh the page, which nowadays in modern SPA applications is something that we try to prevent due to many reasons (reset in-memory data/state, cancel ongoing requests, etc...).

Solution So in short whenever there is a form submission then the needed action is to prevent the default behavior.

In your situation using ReactJS, the form submission is handled inside the handleClick method where the solution would be to handle the event and invoke preventDefault().

e.g.

handleClick(e) {
  e.preventDefault() // prevent the default behavior
  // The rest of your logic...
}
  • Related