noahdubs
noahdubs

Reputation: 89

How to fetch data from express backend using React

Im having trouble accessing data from my backend using express, I am also sort of confused on how i should set up my routing. Do I only need express routes for when I have to dig something out of my database?

My User component

import React from 'react';

class User extends React.Component {
    state = {
        username: ""
    }

    componentDidMount() {
        fetch("/api/:user")
            .then(res =>res.json()
            .then(data => {
                console.log("data", JSON.stringify(data, null, 4));
                this.setState({data}) 
            }))
    }

    render() {
        return (
            <div>
                {this.state.username}
            </div>
        )
    }
}

export default User;

my user routes, the route is /api/:user

router.get("/:user", (req, res)=>{
    // find user
    console.log(req.params);
    User.find({username:req.params.user}, (err, foundUser)=>{
        if(err) {
            console.log(err);
        } else {
            res.json(foundUser);
        }
    });
});

when i console.log(req.params) it returns :user, not the actual user requested

Upvotes: 0

Views: 1481

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

I am giving a sample code for you to learn.

In the App.js we define the routes using react-router-dom package.

import React from "react";
import ReactDOM from "react-dom";
import {
  BrowserRouter as Router,
  Route,
  Redirect,
  Switch,
  Link
} from "react-router-dom";
import Users from "./Users";
import User from "./User";

function App() {
  return (
    <Router>
      <Link to="/">Users</Link>
      <Switch>
        <Route path="/" exact component={Users} />
        <Route path="/:userId/" exact component={User} />
        <Redirect to="/" />
      </Switch>
    </Router>
  );
}

export default App;

In Users component, we get a list of users from jsonplaceholder api and list them, give a dynamic link with a userId to the User component.

import React from "react";
import { Link } from "react-router-dom";

class Users extends React.Component {
  state = {
    users: []
  };

  componentDidMount() {
    fetch("https://jsonplaceholder.typicode.com/users")
      .then(res => res.json())
      .then(users => this.setState({ users }));
  }

  render() {
    return (
      <ul>
        {this.state.users.map(user => (
          <li key={user.id}>
            <Link to={`/${user.id}`}> {user.name}</Link>
          </li>
        ))}
      </ul>
    );
  }
}

export default Users;

In the user component, we get the userId param from this.props.match.params.userId, and using that userId we call another api to get user details.

import React from "react";

class User extends React.Component {
  state = {
    user: null
  };

  componentDidMount() {
    fetch(`https://jsonplaceholder.typicode.com/users/${this.props.match.params.userId}`)
      .then(res => res.json())
      .then(user => {
        this.setState({ user });
      });
  }

  render() {
    const { user } = this.state;

    if (!user) return <div>Loading user...</div>;

    return (
      <div>
        <h1>User Name: {user.name}</h1>
        <p>Email: {user.email}</p>
        <p>Website: {user.website}</p>
      </div>
    );
  }
}

export default User;

Note that we dynamically constructed the user detail api url by with template literal using the backtick character. This was one of the problems you had in your code.

Codesandbox

Upvotes: 1

Exifers
Exifers

Reputation: 2822

In your url, the :user is a way to say in the backend code "a value goes at this place", and this must be the user id from the database I presume.

So in the React code you should do :

const userId = 4 // the id of the user that you want to fetch
fetch(`/api/${userId}`)

Upvotes: 0

Related Questions