Home > Blockchain >  How do i deconstruct a javascript user object to display on an account page?
How do i deconstruct a javascript user object to display on an account page?

Time:03-07

I can't get my account screen to show user details from my DB. I am able to get the user details as an object, but I'm unable to deconstruct it to display just the email, or just the name, etc.

So, here is the AccountScreen.js component. After making the API call I have a console.log(result) and it logs correctly, returning a user object with the email and name. However, where I have {user.email}, nothing shows up. If i put just {user}, I get this error code

"Error: Objects are not valid as a React child (found: object with keys {result}). If you meant to render a collection of children, use an array instead."

import React, { useState, useEffect } from 'react';
import axios from 'axios';
import Cookies from 'universal-cookie';
const cookies = new Cookies();
const token = cookies.get("TOKEN");


function AccountScreen() {
    const [ user, setUser ] = useState("");
    
    // useEffect executes once the page loads 
    useEffect(() => {
        // set configuration for API call
        const configuration = {
            method: "get",
            url: "MYURL/account",
            headers: {
                Authorization: `Bearer ${token}`,
            },
        };
        axios(configuration)
            .then((result) => {
                console.log(result); 
                //assign the User to the in result to User we initialized
                setUser({result});
            })
            .catch((error) => {
                error = new Error();
            });
    }, []);
  
  return(
    <div className="container">
      <h2>
        Dashboard
      </h2>
      <h3>email:{user.email}</h3>
    </div>
  );
}

export default AccountScreen;

I make an API call to the backend, here is the relevant bit of code from there. It successfully returns an object with the email and name, as I want it to.

// authentication endpoint
app.get("/account", auth, (request, response) => {
    User.findOne({email: request.user.userEmail})
        .then((user) => {
            response.status(200).send({
                email: user.email,
                name: user.name,
            })
        })
        .catch((error) => {
            response.status(404).send({
                message: "User not found",
                error,
            })
        });
});

here is the auth component where it returns the user object (which includes users' email), which is what the /account API uses to find the account in the DB.

const jwt = require('jsonwebtoken');

module.exports = async (request, response, next) => {
    try {
        // get the token from the authorization header
        const token = await request.headers.authorization.split(" ")[1];
        // check if token matches the supposed original
        const decodedToken = await jwt.verify(
            token,
            "RANDOM-TOKEN"
        );
        // retrieve the user details of the logged in user 
        const user = await decodedToken;
        // pass the user down to the endpoints here
        request.user = user;
        // pass down functionality to the endpoint
        next();
        
    } catch (error) {
        response.status(401).json({
            error: new Error("Invalid Request!"),
        });
    }
}

To summarize, on my account page it should show the user email next to "email:", however, I have not been able to figure out how to destructure the object to only display that one bit of info, and currently it shows nothing on that page next to "email:" At one point I was using JSON.stringify and was able to get the info to display, but it was displaying the entire object as a string and I only want to display 1 item at a time.

Thank you in advance for your help!

CodePudding user response:

I figured it out! I needed to have it as setUser(result.data); instead of ({result}). I had tried this before but it was while I was also messing with the rest of my code so I must've just fixed the issue I created for myself.

CodePudding user response:

I think i see where the problem comes from.In the server here is the format your returning

{ 
  email:value,
  name : value
}

So it's an objet with 2 attributes email and name.

On the client side, the http client you're using is axios, so when you use axios to grub the data that the server sends it's through the data attribut and not result as it's the case in your distructuring syntax.

So instead of setUser({result}); use setUser({data}); but for that to work you shoul do the distructuring on the response argument that you call result like .then({data})=>{setUser({data})} because in axios that's the attibutes that gives you access to data from the server.

Here is the doc explaining about that data attribue : Response Schema

  • Related