question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Bug with transformResponse and transformRequest functions/arrays/objects

See original GitHub issue

Summary

tl;dr utils.merge break transformResponse and transformRequest behaviour in certain scenarios.

There are 3 parts of the problem.

Inconsistency between types in configs when setting transform* directly via axiosInstance.defaults.transform* and using axios.create(config)

The problem is that when setting directly one would set it as e.g. axios.defaults.transformRequest = [f1, f2, f3] but when passing the same array via config it will get mergeda and become {0: ƒ, 1: ƒ, 2: ƒ}

axios.create = function create (instanceConfig) {
  return createInstance(utils.merge(defaults, instanceConfig))
}

and the merge function forces the array to become an Object with numbers converted to strings as keys. That of course breaks a quite simple situation showed even in examples/transform-response/index.html

transformResponse: axios.defaults.transformResponse.concat(function (data, headers) {

Theoretically it still works as we can access this object via [number] but it seems as not quite expected behaviour. Additionality when using typescript transformResponse?: AxiosTransformer | AxiosTransformer[]; becomes very not true 😉 and even can be a big problem when using a type guard if (transformResponse instanceof Array) {

Wrong behavior when merging defaults with per request config

Because of the merge method and the array becoming an Object we might encounter a totally unexpected behaviour when using axios.get('url', { transformResponse: mySpecialOneTimeTransform });

a = ['1', '2']
b = ['3']
utils.merge(a,b)
{0: "3", 1: "2"}

IMO that is the least expected behaviour when passing config to single request.

And that brings us to the last problem.

The by design problem

  1. When creating an axios instance - should the transforms be merged or overwritten.
  2. When passing a config per request - should the transforms be merged or overwritten.
    • merging - then there is no possibility to exceptionally not apply the default transforms [bad idea], also we should at least keep the order
    • overwriting - that’s kinda ok, we could then add a new transform by taking the defaults and concat a new transformer(as shown in example)
    • adding new api methods to transform* for adding and removing functions (that’s becoming weirdly similar to interceptors)
  3. Do we really need to have AxiosTransformer | AxiosTransformer[] i suppose allowing only an array would be better. (That could be a breaking change, but probably acceptable as we are expecting release 1.0)

This issue is strongly connected with #1109 and might be connected with multiple defaults and config issues from the checklist in #1333.

Possibly quite a lot of this will be solved when checklist item Substitute custom utils with lodash is finished.

Context

  • axios version: e.g.: v0.17.1
  • Environment: e.g.: node v8.9.3, windows 10

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:6

github_iconTop GitHub Comments

3reactions
AllainPLcommented, Mar 30, 2018

Any update on the situation? I might be able to help make a PR or sth - but some feedback would be welcome 😃

2reactions
eithedcommented, Mar 27, 2019

The workaround that worked for me was this:

axios.interceptors.request.use(function(config) {
  if (!config.data)
    config.data = {}

  // assign your variables here
  config.data.foo = 'bar'
  
  return config;
}, function (error) {
  // Do something with request error
  return Promise.reject(error);
});

Bear in mind that config.data at this point contains combined values from your config and the request, so if you’re wanting to implement proper shadowing of values (starting with empty object, first the values from config should apply, then the values from transformRequest, then the values from request), then you’re out of luck.

Read more comments on GitHub >

github_iconTop Results From Across the Web

What is the default transformResponse and transformRequest ...
I've discovered I can do so by changing transformRequest and transformResponse default methods in $http config. My question is this.
Read more >
Difference between transformResponse and ...
It seems like transformResponse is simpler but lacks the ability to use async code, but response interceptors are more powerful, at the expense...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found