When you call it in http://localhost:9000/testApi, it works fine.
testAPI.js
const express = require('express');
var router = express.Router();
router.get("/",function(req,res){
res.send("API is working fine");
});
module.exports = router;
But Calling in ReactJS functional component leads to nothing
import React, {useState, useEffect} from 'react';
import TopicCard from './TopicCard.js'
import './HomePage.css'
function HomePage() {
const [apiResponse,setApiResponse] = useState('Loading..')
const url = "http://localhost:9000/"
useEffect(() => {
fetch(url).then(res => setApiResponse(res.data))
}, [])
return (
<>
<h1>Choose a topic to learn {apiResponse}</h1>
</>
);
Console.log gives this
Promise {}[[Prototype]]: Promise [[PromiseState]]: "rejected" [[PromiseResult]]: SyntaxError: Unexpected token A in JSON at position 0
While the Class Component is working perfectly fine
import React, {Component} from 'react'
class Test extends Component {
constructor(props) {
super(props);
this.state = { apiResponse: "" };
}
callAPI() {
fetch("http://localhost:9000/testAPI")
.then(res => res.text())
.then(res => this.setState({ apiResponse: res }));
}
componentWillMount() {
this.callAPI();
}
render()
{
return (
<div>
<p className="App-intro">;{this.state.apiResponse}</p>
</div>
);
}
}
export default Test
CodePudding user response:
Are you confusing routes / end points with file names? testAPI.js is your file name. It's not your endpoint.
You call:
const url = "http://localhost:9000/testAPI"
useEffect(() => {
fetch(url).then(res => setApiResponse(res.data))
}, [])
But your endpoint is - a forward slash '/' i.e. the root (not ROUTE) :
router.get("/",function(req,res){
res.send("API is working fine");
});
Try changing to this:
const url = "http://localhost:9000/"
useEffect(() => {
fetch(url).then(res => setApiResponse(res.data))
}, [])
If you want to fetch const url = "http://localhost:9000/testAPI" from react then change the endpoint to: const url = "http://localhost:9000/testAPI" else server won't know of it.
CodePudding user response:
No differences are between functional and class-based components.
The Problem
You forgot to parse your response as a text in the fetch
method.
The Solution
parse your data as a text
and then store it on your state variable
useEffect(() => {
fetch(URL)
.then(res => res.text())
.then(res => setApiResponse(res))
.catch(err => console.warn(err))
}, [])
Note: don't forget to use catch
method for your asynchronous fetch API.
Explanation
When your data (API call response) is in standard JSON format, you need to parse them with .json()
method, and usually, a data
property holds the whole response, but in your case (with a text as a response) it's not useful.