-1

I am working on a project that uses Laravel for back-end and React for front-end.

Whenever the user clicks login, a modal will open that will, up on submitting, fetch the users bearer token.

These fetch functions are all located inside AuthService.js

export function getLoginToken(email, password) {
    fetch("/api/login", {
        method: "post",
        credentials: 'include',
        headers: {
            'Accept': 'application/json',
            "Content-type": "application/json",
        },
        body: JSON.stringify({
            'email': email,
            'password': password
        })
    }).then((response) => response.json())
        .then((responseJSON) => {
        return responseJSON;
    })
}

The Nav component is where the login button resides, so I'm importing and using the funcionts that I've created inside AuthService.js

When I console log the json result within the actual getLoginToken function, there is no problem. Because up on placing it inside .then() it waits for it to complete so it doesn't result in undefined.

Now.. Inside the Nav component, there is an onClick function bound to the login button, which will execute AuthService.getLoginToken(email, password)

Actual problem:

I would like to store the response data inside a variable, but i keep getting undefined. This because I'm trying to insert asynchronous data inside a synchronous function.

I've also tried:

AuthService.getLoginToken(loginEmail, loginPassword).then((result) => {
            this.setState({
                token: result
            });
        });

But this will also return: Cannot read property 'then' of undefined.

Any ideas on how to fix this?

Regentix
  • 293
  • 1
  • 4
  • 14
  • 2
    [Drop the pointless `.then((responseJSON) => { return responseJSON; })`](https://stackoverflow.com/q/41089122/1048572) and instead put a `return` in the beginning of the `getLoginToken` function, so that you return the chained promise. Then you can use the syntax in your second snippet – Bergi Sep 27 '18 at 13:08
  • You can’t do fetch in normal JavaScript function because fetch only works when a class extends the component. Also this won’t be available in normal JavaScript function until and unless you pass this as a param to the function – Hemadri Dasari Sep 27 '18 at 13:10
  • @Bergi will the fetch work in normal JavaScript function? – Hemadri Dasari Sep 27 '18 at 13:11
  • 1
    @Think-Twice Why wouldn't it? It's a function that can be called after all, from anywhere. – Bergi Sep 27 '18 at 13:14
  • Ok what I thought was fetch is bound to the component but not a regular JavaScript function. Like component this won’t be available until we pass this from component to the function so I thought fetch also works in similar way – Hemadri Dasari Sep 27 '18 at 13:17
  • @Think-Twice [Fetch API](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) – Alexander Azarov Sep 27 '18 at 13:21
  • @Alexander thanks for pointing me to the right path. My understanding was completely wrong I always thought fetch is a concept behind react but I never know it’s belongs to JavaScript. ThankQ I learned something new for the day :) – Hemadri Dasari Sep 27 '18 at 13:26

2 Answers2

-2

Try this

export function getLoginToken(email, password) {
  return fetch("/api/login", {
    method: "post",
    credentials: 'include',
    headers: {
        'Accept': 'application/json',
        "Content-type": "application/json",
    },
    body: JSON.stringify({
        'email': email,
        'password': password
    })
}).then((response) => response.json())
    .then((responseJSON) => {
    return responseJSON;
})
}

Proper way would be to use state management tool like redux

Mustafa Mamun
  • 2,591
  • 2
  • 14
  • 17
  • I've implemented Flux as state management tool, I was planning on setting bearer tokens inside the `handleLogin` function. Is this the proper way? – Regentix Sep 27 '18 at 13:14
  • please leave your comment while negative marking. I would also like to know what I was missing !! – Mustafa Mamun Sep 27 '18 at 13:37
  • @Regentix I haven't used flux, so cannot really say what would be the proper way. However does the solution work for you? – Mustafa Mamun Sep 27 '18 at 13:44
-2

You can use async await. Or use redux-thunk if you are doing redux.