Conditional creating new objects with spread operator

original blog post
I am lazy and I am not shy of it. Today I refactor some vuex (state manager) modul called Search. Yes, it handles search stuff from application. But what is interesting, it uses 2 endpoints for search (because of server API). One use searchText in query parameter (https://localhost:5000/items?searchText=valueInSearchText) but second in route parameter (https://localhost:5000/items/valueInSearchText).

In project we use axios like async http client (yes, that one, which is based on JavaScript Promises). Api of axios for GET method consumes url (requestedUrl : string) and configuration (config : AxiosRequestConfig).
Important part is that config argument, which contains besides others also query parameters for request.

Now the problem. I wanna create AxiosRequestConfig just from one place. One with query parameters and other one without query parameters. So I firstly wrote code like this:

const axiosRequestConfig = {
    withCredentials: true,
    cancelToken: cancelToken,
}

if(useMultilineSearch){
    axiosRequestConfig.params = {
        'addrs': searchText
    }
}

But what's wrong with this? I create const variable and I mutate their state after creation 🤦‍♂️. Yes, I could create factory method createRequestConfig, but what if I told you, that you could use something built in JavaScript?

Spread syntax

Spread operator used for create new objects (sample code):

const user = { name: "Fero", age: 52 }
const admin = { createUser: function(user) {/*...*/}, ...user }

How does it work? Maybe as you expected - object admin has function createUser and properties name and age. But how could this help me with my problem with creating axiosRequestConfig?

Consider following code samples:

const axiosRequestConfig = {
    withCredentials: true,
    cancelToken: cancelToken,
    ... (useMultilineSearch && { params : {'addrs': searchText }})
}

How does it work? It is really easy - if useMultilineSearch is set to true, it creates object { params : {'addrs': searchText }}. After deconstructing, this object is in result merged to axiosRequestConfig.

{
  "withCredentials": true,
  "cancelToken": "value of cancellation token",
  "params": {
    "addrs": "value of addrs"
  }
}

If value of useMultilineSearch is set to false, it creates following object:

{
  "withCredentials": true,
  "cancelToken": "value of cancellation token"
}