1

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

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

Comments

0

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.

9 Comments

localhost:9000/testAPI is giving proper response. But in Reactjs, it is returning undefined
As I said this const url = "localhost:9000/testAPI" is NOT the end point. You need to call this const url = "localhost:9000" since you built this in you testAPI file.
In your react DO NOT call "localhost:9000/testAPI" BUT call "localhost:9000"
Also try to log res in console and log res.data. Are they undefined?
fetch(url) resolves to a Response which doesn't have a data property. It should be fetch(url).then(res => res.text()).then(setApiResponse)
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.