uinstinct
uinstinct

Reputation: 740

How to get the redirected response from axios?

I don't think there is a problem with the request because I have used the same request for posting a new character and it succeded. I think the problem is with the response.

Backend using Express and Node

I have an API route which updates a character.

router.put('/:id', (req, res, next) => {
    const { id } = req.params;
    Promise.all([
        updateAbilities(id, req.body.abilities, next),
        updateCharacter(id, req.body.name, req.body.img, next),
        updateShows(id, req.body.shows, next)
    ])
        .then(values => console.log(values, 'are the values received at put request'))
        .then(() => res.redirect('/' + id))
        .catch(err => next(err));
})

When I am sending the request using Postman, I am getting the perfect response.

Image of postman response

Frontend in React App using Axios

I am performing the same request on a React App using Axios.

export async function updateOne(inputs, cid) {
    inputs = {
        name: "green latern 2",
        abilities: "ring, superpower",
        shows: "justice league",
        img: "an image",
    };
    cid = 11;
    let err = null
    const response = await axios({
        method: 'PUT',
        url: BASE_URL + cid,
        data: inputs
    }).catch(e => err = e);

    console.log(response, 'was the response');
    return;
}

But on doing so, I am getting this error:

Error: Network Error
    createError createError.js:16
    handleError xhr.js:83
    dispatchXhrRequest xhr.js:80
    xhrAdapter xhr.js:12
    dispatchRequest dispatchRequest.js:52
    promise callback*request Axios.js:61
    wrap bind.js:9
    updateOne apiCalls.js:36
    js apiCalls.js:66
    Webpack 22
 was the response apiCalls.js:42

The Code can be found on GitHub : https://github.com/uinstinct/card_builder

If you need more information, I shall provide what you need. Please a comment for the same

Upvotes: 1

Views: 23288

Answers (3)

uinstinct
uinstinct

Reputation: 740

After going through almost all the search results of this similar question, I figured out these:

  • Data from a redirected url ( redirected by the backend itself ) cannot be handled by any library - Be it axios or fetch or XMLHttpRequest itself

This cannot happen because the backend application ( in this case: express ) send res.status.code of 302 which basically tells the browser that : "the data, you are looking for, cannot be found in this url but in the url I am redirecting you to"

This code simply won't work in any library:

app.get("/i/came/here",function(req,res){
 return res.redirect("/now/go/here"); // the actual data stored here
}

You might even get a CORS error

  • If you trying to redirect to a url, that might not even work with axios or fetch unless you use an interceptor or some other kind of middleware or function to handle the handle error.

Yes, axios will always throw an error whenever the backend tries to produce a redirect

More on this here : https://github.com/axios/axios/issues/932#issuecomment-307390761

  • There is no way ( that I found ) which can get the redirected data from the url axios will always be throwing an error when you try to do that. The best possible solution ( that I found ) is to handle the resultant data in the backend application itself.

For the particular problem dealt in this question, I changed the backend route which updates a character like this :

router.put('/:id', (req, res, next) => {
    const { id } = req.params;
    Promise.all([
        updateAbilities(id, req.body.abilities, next),
        updateCharacter(id, req.body.name, req.body.img, next),
        updateShows(id, req.body.shows, next)
    ])
        .then(values => console.log(values, 'are the values received at put request'))
        .then(() => getOneById(id,res))
        .catch(err => next(err));
})

I used a function called getOneById(id,res) which handles the logic for getting the particular character and sending a json response.

I am welcome to all edits and suggestion. Please do correct if I am wrong. Please leave a comment below for the same

Upvotes: 9

Reyno
Reyno

Reputation: 6505

Your Postman request makes use of x-www-form-urlencoded you need to convert your inputs object into an url encoded string.

Also change the axios content-type header to x-www-form-urlencoded since by default it is application/json

headers: {
  "Content-Type": "application/x-www-form-urlencoded"
}

const inputs = {
  name: "green latern 2",
  abilities: "ring, superpower",
  shows: "justice league",
  img: "an image",
};


const urlencoded = Object.entries(inputs).map(([key, value]) => {
  return encodeURIComponent(key) + "=" + encodeURIComponent(value);
}).join("&");

console.log(urlencoded);

Upvotes: 0

Dom
Dom

Reputation: 734

In Postman you send the data as x-www-form-urlencoded. Axios probably sends your data as JSON with a content-type of application/json. Is your express App able to handle json requests? You need to use bodyParser middleware:

Via npm: npm i body-parser

In your app, you need to require it and then use the middleware:

const bodyParser = require('body-parser');
// ...
// ...
app.use(bodyParser.json());

Edit: as pointed out in the comments you can also use the express.json() middleware, which is the same.

app.use(express.json());

...without any installs.

Upvotes: 0

Related Questions