danpaz / bodybuilder

An elasticsearch query body builder :muscle:

Home Page:http://bodybuilder.js.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Option to clone a body

roman-16 opened this issue · comments

commented

There should be an option to clone a body and mutate it without mutating the old body.
Something like this:

// {"size":2}
const a = bodybuilder()
  .size(2);

// {"size":2,"from":1}
bodybuilder(a.build())
  .from(1)
  .build();

In this example a should still only contain size. I think the new argument in bodybuilder should be a json string an not a bodybuilder instance because this would support hardcoded jsons too.

There are so many tools that provide this functionality.

//lodash
_.clone()
_.cloneDeep()

// raw JS
const clone = Object.assign( {}, bodybuilder);

I think the new argument in bodybuilder should be a json string an not a bodybuilder instance because this would support hardcoded jsons too.

I don't think it would be straightforward to produce a bodybuilder instance from JSON, especially with multiple levels of nesting. The only option I see is to clone the bodybuilder instance as shown above.

commented

@ferronrsmith I tried your suggestion but it doesn't work for me.

// {"size":2}
const a = bodybuilder().size(2);

// {"size":2,"from":1}
const b = _.cloneDeep(a).from(1);

console.log(JSON.stringify(a.build()) === JSON.stringify(b.build())); // true
commented

You can even try this on your website. Open your browser console and paste this in.

const a = bodybuilder().size(2);
const b = Object.assign({}, a).from(1);

console.log(JSON.stringify(a.build()) === JSON.stringify(b.build())); // true

It has to do with the body construction. Since clone/deep clone can't recreate an object inside an isolate scope. It wouldn't be possible without a change.

commented

I would really appreciate if you could implement this feature.

as @danpaz said it isn't straightforward, because of how bodybuilder object is constructed.

commented

So it's not being implemented?

no

It's not per se cloning, but one thing I've been doing a lot is

const filterBuilder = bodybuilder()

// add some filters to this filter builder...


// now I need an aggregation with that filter
const builder = bodybuilder()
builder.getFilter = () => filterBuilder.getFilter()

afterwards you have two separate instances, both will use the same filter.

I can imagine that we include something like this more deeply in bodybuilder. There are probably 1000 nuances that you may want to see done in a different way, but this is something that may work for your case @wa4-fearless-otter

And the same works for getQuery and getAggregations

commented

@johannes-scharlach I already added a clone function with #247

Thanks, I just noticed. Great job!