1

I am using React, node.js and this is my first time using Axios to connect to my Java/SpringBoot Rest GET service (fetch all) on localhost:8080 which returns a list of saved users as a JSON array. What I am trying to achieve is to successfully connect and retrieve the REST data with Axios GET but I got the following error:

Failed to compile

src\App.js
  Line 16:7:   'setIsLoaded' is not defined  no-undef
  Line 17:7:   'setRowData' is not defined   no-undef
  Line 35:13:  'rowData' is not defined      no-undef

I suspect perhaps I haven't imported some components properly?

Here is my code :

import React, { useEffect } from "react";
import { axios } from 'axios';
import { jsonServerRestClient, Admin, Resource, Delete } from 'admin-on-rest';
import { DataGrid } from '@material-ui/data-grid';

 
export default function App() {


useEffect(() => {
  const apiurl = "http://localhost:8080/user/all";
  axios
    .get(apiurl)
    .then((response) => response.data)
    .then((data) => {
      setIsLoaded(true);
      setRowData(data);
    });
}, []);



const columns = [
  { field: "id", headerName: "ID", width: 10 },
  { field: "userName", headerName: "Name", width: 170 },
  { field: "userTelNo", headerName: "Tel No", width: 70 },
  { field: "userEmail", headerName: "EMail", width: 100 },
  { field: "userRole", headerName: "Role", width: 100 },
];



  return( 
    <DataGrid
      rows={rowData}
      columns={columns}
      id="id"
      pageSize={15}
      checkboxSelection
    />
  );

  }

I confirmed that upon checking the GET URL on my browser address bar (http://localhost:8080/user/all), the JSON is returning properly (as an array of JSONs) as shown below:

[{"id":1,"userName":"admin","userPassword":"admin123","userTelNo":"012-104-1001","userEmail":"admin@fsgsm.com","userRole":"管理员","loginDateTime":"2021-01-25T09:57:38","entryDateTime":"2021-01-25T09:57:31","updateDateTime":"2021-01-25T09:57:40"},

{"id":2,"userName":"t","userPassword":"admin123","userTelNo":"","userEmail":"","userRole":"开发 人员","loginDateTime":"2021-01-25T11:15:53","entryDateTime":"2021-01-25T11:15:53","updateDateTime":"2021-01-25T11:15:53"},

{"id":3,"userName":"324","userPassword":"43444","userTelNo":"4334","userEmail":"344","userRole":"开发 人员","loginDateTime":"2021-01-25T23:12:38","entryDateTime":"2021-01-25T23:12:38","updateDateTime":"2021-01-25T23:12:38"}]

EDIT:

I've simplified my program a bit to get to the bottom of things as below and I found out that it seems to be a CORS issue from the server backend :

Simplified code:

import React from 'react';
import { axios } from 'axios';

 
export default function App() {

  const axios = require('axios').default;

  axios.get('http://localhost:8080/user/all')
  .then(function (response) {
    // handle success
    console.log(response);
  })
  .catch(function (error) {
    // handle error
    console.log(error);
  })
  .then(function () {
    // always executed
  });


  return null;


  }

The error message from Chrome Developer Tools (F12) :

Access to XMLHttpRequest at 'http://localhost:8080/user/all' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

so I guess I have to find a way for my Java SpringBoot backend user REST service to "give permission" for http://localhost:3000 to access it. Anyone know how can this be done?

Ezani
  • 535
  • 3
  • 18
  • 1
    Where does (eg.) `setIsLoaded`, come from? Does the code set such up correctly, such as with `const [isLoaded, setIsLoaded] = useState(false);` ..? – user2864740 Jan 26 '21 at 03:06
  • If I just get rid of the lines setIsLoaded(true); and setRowData(data); and just use data directly, would it be possible? – Ezani Jan 26 '21 at 04:07
  • 1
    I can tell what your code is doing, but not what it's supposed to be doing. Where are these three undefined variables `setIsLoaded`, `setRowData`, and `rowData` supposed to be coming from? Are they from `props` or from `state`? I think the other comment is correct in assuming that you meant to include `const [rowData, setRowData] = useState([]);` but you haven't. – Linda Paiste Jan 26 '21 at 04:30
  • 1
    It is not possible to use the the data directly from a `useEffect` hook without storing it to state. The variable `data` is a local variable which only exists inside the context of your `useEffect` callback. You cannot use it in your component's `return`. – Linda Paiste Jan 26 '21 at 04:32

2 Answers2

4

you mentioned you are getting this in chrome console

Access to XMLHttpRequest at 'http://localhost:8080/user/all' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

That is CORS(Cross origin resource sharing) issue you are facing which happens when you send the requests from browser and in response, browser expects some set of headers in response which indicates to browser that server wants to serve requests from this current origin in browser or not.
To solve this, at the spring boot side, you have to use CrossOrigin annotation which lets the backend add the required CORS headers in the response for request coming from different origins.

so add this annotation

@CrossOrigin(origins = "http://localhost:3000")

to your RestController class

If you want to indicate to browser that server allows request from any origin on spring boot server, then modify the cross-origin annotation to

@CrossOrigin(origins = "*")

or

@CrossOrigin
mss
  • 1,423
  • 2
  • 9
  • 18
1

From the FrontEnd side, I do not see any state being declared within the component, that's why you are getting the error.

Failed to compile

src\App.js Line 16:7: 'setIsLoaded' is not defined no-undef
Line 17:7: 'setRowData' is not defined no-undef Line 35:13: 'rowData' is not defined no-undef

You need to add the state first.

import {useState} from "react";

export default function App() {
   const [isLoaded,setIsLoaded] = useState(false); // isLoaded State
   const [rowData,setRowData] = useState([]); //rowData State

useEffect(() => {
  const apiurl = "http://localhost:8080/user/all";
  axios
    .get(apiurl)
    .then((response) => response.data)
    .then((data) => {
      setIsLoaded(true);
      setRowData(data);
    });
}, []);



const columns = [
  { field: "id", headerName: "ID", width: 10 },
  { field: "userName", headerName: "Name", width: 170 },
  { field: "userTelNo", headerName: "Tel No", width: 70 },
  { field: "userEmail", headerName: "EMail", width: 100 },
  { field: "userRole", headerName: "Role", width: 100 },
];



  return( 
    <DataGrid
      rows={rowData}
      columns={columns}
      id="id"
      pageSize={15}
      checkboxSelection
    />
  );

  }
Imran Rafiq Rather
  • 7,677
  • 1
  • 16
  • 35