0

I am sorry if it is simple question, I'm new to javascript

So I have simple axios GET request. It is used three times in my code, so I thought that I could make it an external function, to avoid duplicating code, to making it cleaner and easy readable

The problem is when I call to that function, return value is undefined. And this is because code is working like synchronous. So I thought that I need to make the function return a Promise, and in function call I have to use async/await or then syntax to get the response in the right time. But after many tries code is still running as synchronous

I read a lot of theory on promises and how they work, got a solid understanding of when they change states, but something goes wrong when I try to implement them on my own



Here is the function that retrieves data

const getMessagesFromChat = async (JWT_header, chatId) => {

    if (JWT_header !== '') {
        //1 let messages
        //4 return
        axios.get(`${SECURED_API_PATH}/messages/chat/${chatId}`, {
            headers: {authorization: JWT_header},
            params: {size: 80, page: 0}
        })
            .then(response => {
                console.log('messages (fetch)', response.data)
                //1 messages = response.data
                //1 return messages
                return response.data  //2
                //3 return Promise.resolve(response.data)
            })
            .catch(error => {
                console.log(error, error.response)
            })
        //5 return Promise.resolve(messages)
    }
}

I marked comments with numbers based on what I've tried

  1. make a variable and return it in then block
  2. make function async so everything it returns is wrapped in promise
  3. return explicit promise using Promise.resolve() in then block
  4. return the whole request as a promise
  5. return explicit promise using Promise.resolve() after the request


All responses except 4 were undefined. In 4 variant log statement shows the promise object itself instead of promise value. In other variants log statement shows first `undefined` response and then the actual response from request I tried to implement second advice from https://stackoverflow.com/questions/45620694/how-to-return-response-of-axios-in-return/45622080 but it did not work.

This is the function I tried to use to get the result (onClick)##

const selectChat = () => {
        const JWT_header = getToken()
        if (JWT_header !== null) {
             try {
                 const messages = await getMessagesFromChat(JWT_header, chatId)
                 console.log('messages (after fetch)', messages)
                 //setMessages(messages)
             } catch (error) {
                 console.log(error)
             }
        } else {
            setIsLoggedIn(false)
        }

or

const selectChat = () => {
        const JWT_header = getToken()
        if (JWT_header !== null) {
             getMessagesFromChat(JWT_header, chatId)
             .then(response => {
                console.log(response)
                setMessages(response)
              })
             .catch (error =>console.log(error))
        } else {
            setIsLoggedIn(false)
        }

But none of them worked as expected

What am I doing wrong?

asteoff
  • 13
  • 5
  • 1
    `getMessagesFromChat` doesn't return anything. You need `return axios.get/* ... */` – VLAZ May 12 '21 at 16:39

1 Answers1

1

Your function doesn't return anything. A return statement in a then callback is not sufficient, you'd still have to return the promise chain itself from the outer function.

Use either .then() syntax:

function getMessagesFromChat(JWT_header, chatId) { // no `async` here
    if (JWT_header !== '') {
        return axios.get(`${SECURED_API_PATH}/messages/chat/${chatId}`, {
//      ^^^^^^
            headers: {authorization: JWT_header},
            params: {size: 80, page: 0}
        }).then(response => {
            console.log('messages (fetch)', response.data)
            return response.data
        })
    } else {
        return Promise.resolve(undefined)
//      ^^^^^^ important for chaining
    }
}

or async/await syntax:

async function getMessagesFromChat(JWT_header, chatId) {
    if (JWT_header !== '') {
        const respnse = await axios.get(`${SECURED_API_PATH}/messages/chat/${chatId}`, {
//                      ^^^^^
            headers: {authorization: JWT_header},
            params: {size: 80, page: 0}
        });
        console.log('messages (fetch)', response.data)
        return response.data
    }
    // else return undefined
}
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    Thank you, that was helpful, especially the .then syntax example Guess I need to understand basics of promises before going to async/await – asteoff May 12 '21 at 16:57