1

I currently have my userInfo stored in a state

const [users, setUsers] = useState([])

Please, how do I pass the userId into the axios URL to be able to fetch the posts of a specific user. see what I did below. I know I am getting it wrong but please help me.

Dashboard Component

const Dashboard = () => {

const getPost = () => {   

    axios.get(`/api/getpost/${users._id}`, //I want to fetch the userID on this URL. That measns it is to replace ${users._id}
     {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
      setUposts(response.data)
    })
  }
  useEffect(() => {
    getPost()
  }, [])


return (
//something here

)
}

UserSchema This is my userSchema

const userSchema = new Schema({
    username: {
        type: String,
        required: true
    },
    roles: {
        User: {
            type: Number,
            default: 2001
        },
        Mentor: Number,
        Admin: Number
    },
    password: {
        type: String,
        required: true
    },
    userID: {
        type: String,
        required: true
    },
    Profile: {
        type: mongoose.Schema.Types.ObjectId,
        ref: "profile",
    },
    refreshToken: String
});

const User = mongoose.model('user', userSchema);

module.exports = User;

API TO GET USER POST This is how I find the user by their id from the database and populate

router.get('/getpost/:id/', (req, res) => {
    const id = req.params.id;    
    // const profID = req.params.prof_id; 
    Userpost.find({User:id}).populate('User', {password: 0}).populate('Profile').exec((err,docs) => {
        if(err) throw(err);
        res.json(docs);
    })
});

HOW I setUsers The code below show how I did set the User in state.

 const getUser = () => {
    axios.get('/api/users', {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
      setUsers(response.data)
    })
  };
  useEffect(() => {
    getUser()
  }, [])
SwiftDev
  • 61
  • 1
  • 6

4 Answers4

1

The Question is where do you setUsers we need to know whats inside. And specially where the setUsers is called. A state always needs time to get set. its not set just because you call it. You should try it with a let if it changes and if you need it right away

const getUser = () => {
    axios.get('/api/users', {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
     let user = response.data
    })
  };
  useEffect(() => {
    getUser()
  }, [])

just use the the variable user(like above) instead of the user State.

useState() undefined in React just after set

has a long and right explanation to it.

Daniel
  • 164
  • 7
  • I have updated the question with how I set the Users – SwiftDev Nov 21 '22 at 10:36
  • @user68484 so it happens in the same file and both as the first call? problem is that state only gets set after those finish. So user should be a let then you can use it instantly – Daniel Nov 21 '22 at 10:40
  • @user68484 you can also test that behaviour with a console.log() with useState and no default for it the state will first show you undefined . but the "let" lets you see the value instantly – Daniel Nov 21 '22 at 10:42
  • With the use of "let", I got the value in the console. When I passed it to the url, as @{user._id} , it didn't work. The get API to fetch user from DB and to fetch the post from DB are in the same component – SwiftDev Nov 21 '22 at 14:32
  • @user68484 sorry for the late answer you should get an array if you dont fetch it with first. so you gotta use user[0].id (in case its named id but that you can see with the console log) axios.get(`/api/getpost/'+user[0].id or if its not an array without [0] – Daniel Nov 21 '22 at 22:40
  • Thanks. Your response time is just fine. I will try this out later today. Thank you very much – SwiftDev Nov 22 '22 at 09:26
  • 1
    Thank you very much. I have been able to get it work using the variable. It works perfectly. I'll update the question above with how I got it done – SwiftDev Nov 23 '22 at 06:53
1

Assuming that you are calling getUser() api first and setting the details of user before you call getPost() api in useEffect. You can pass userId as an argument to getPost() function. In useEffect when you call getPost(), you will have your user data and as you are storing it in array you need to access it in form of array like:

users[0].userId.

So you can do implement the code in this way:

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
const Dashboard = () => {

const getPost = (userId) => {   

    axios.get(`/api/getpost/${userId}`, 
     {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
      setUposts(response.data)
    })
  }
  useEffect(() => {
    getPost(users[0].userId);
  }, [])


return (
//something here

)
}
  • This worked well when I just entered it. On refreshing, the screen went blank and it throws and error on the console that it cannot read properties of undefined (reading '_id). – SwiftDev Nov 21 '22 at 11:25
  • It might happen because the data of user is not stored and you are trying to access it. Meaning that useEffect is called before the getUser() api is called which uses setUser() function to save user data. So make sure that the details of users are set before you call getPost() api in useEffect. – KARAN DOSHI Nov 21 '22 at 11:32
  • Please do you have a sample code on how to get this done?. I so much appreciate your help – SwiftDev Nov 21 '22 at 11:37
  • I do not have sample code right now, but i have an idea what can be done. You can do something like: useEffect(()=>{ getUser(); getPost(user[0].userId); },[]); getUser will bring user data and store it in user state, then you can call getPost() function and send the user id as argument to the getPost() function. – KARAN DOSHI Nov 21 '22 at 12:07
  • Seems there's something wrong somewhere. I may just try some more to figure it out. Thank you very much for your assistance. – SwiftDev Nov 21 '22 at 12:26
  • OK if you need any more help feel free to connect – KARAN DOSHI Nov 21 '22 at 12:36
0

Replace it to:

axios.get(/api/getpost/${users[0]._id},

Thaiyalnayaki
  • 148
  • 1
  • 8
0

THIS WAS HOW I WAS ABLE TO FIX THIS

Using a variable to store the userInfo which includes the UserId (_id) as recommended by Daniel. That makes it immediately available for an API call in the URL on the next line. user[0]._id.

const getUserPost = () => {
    axios.get('/api/users', {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
     let user = response.data

    axios.get(`/api/getpost/` + user[0]._id, {
      withCredentials: 'true',
      headers: {
          'Accept': 'application/json',
          'Content-Type': 'application/json'
      }
    })
    .then((response) => {
     setUposts(response.data)
    })
  })

  };
  useEffect(() => {
    getUserPost()
  }, [])
SwiftDev
  • 61
  • 1
  • 6