user1873196 user1873196 - 3 months ago 17
TypeScript Question

how to assign a const object to be used as a template

I am constructing elasticsearch queries and would like to use object templates for building the POST body of the queries, before sending to my data service.

The query builds great the first time, however, as I use the templates, the actual const objects I declared are changed, and the template is broken after that. In the code below, not only is the retunQuery value changed, but the value of the INIT_QUERY const is changed the same. How can I use this const object as a template, without actually changing it's value.

const INIT_QUERY = {
"query": {
"filtered": {
"filter": {
"bool": {
"must": <any>[]
}
}
}
}
}

const MATCH_QUERY = {
"match": <any>{}
}
...

export class QueryBuilder {

constructor() {}

buildQuery() {
let returnQuery = INIT_QUERY;
.... loop

let query = MATCH_QUERY;
query.match[dbfield].query = 'fieldValueToSearch';

returnQuery.query.filtered.filter.bool.must.push(query);

.... end loop

return returnQuery;
}

}

Answer

let returnQuery = INIT_QUERY; just creates another reference to INIT_QUERY. Both refer to the same object.

Object.assign({}, INIT_QUERY); will only create a shallow copy, so it won't be enough.

The easiest way I see is to provide your "template" as JSON and create new objects from that.

This will break intellisense though. You will need to create an interface and do a type cast.

interface Query {
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": any[]
        }
      }
    }
  }
}
const INIT_QUERY = `{
  "query": {
    "filtered": {
        "filter": {
            "bool": {
                "must": []
            }
        }
    }
}`;
let query: Query = <Query>JSON.parse(INIT_QUERY);