TNG / ngqp

Declaratively synchronize form controls with the URL

Home Page:https://tng.github.io/ngqp

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Programmatically delete/remove/reset queryForms and queryParams

verfault opened this issue · comments

Hello.
Could you give a hint:

  1. Is here any way to do full reset of a QueryForm programmatically? (same as Angular Reactive Forms' reset() method).
  2. What method should I call to unsync URL from QueryForm programmatically?
    I mean I want to use a method of a queryParam like clear() to clear my input's data from URL and unsync it from QueryForm in my .ts file.

Thanks.

Hi!

reset can be essentially mimicked using setValue({})¹ since ngqp has no notion of pristine/dirty and no nesting, so all that reset would do is clear out the values anyway. The only caveat here would be emptyOn handling. Given that in the Forms API reset doesn't "unbind" the form either, is there anything in particular you'd be missing doing this?

As for the "unsynchronizing" part: Could you outline the use case in which you would need this?

¹ We should probably allow setValue(null), which I don't think we currently do. Edit: PR opened for this.

I mean I want to use a method of a queryParam like clear() to clear my input's data from URL and unsync it from QueryForm in my .ts file.

If you're talking about taking a specific QueryParam out of the QueryParamGroup, you can do so using QueryParamGroup#remove. This will remove it from the synchronization process.

Thank you for a quick response!

To be honest, mimicked methods and "emtpy-on-bottle-neck" might be tricky and unintuitive withoup deep knowledge so i assume that adding a hint to the docs would be a great idea, wouldn't it?

My bad that I've given an abstract situation.
The case:

  1. I have a queryGroup with one queryParam which is q for some searching stuff.
  2. For example, my markup is right below:
<div class="search">
  <form
    class="search__form"
    [queryParamGroup]="queryGroup"
  >
    <label for="search-input">Some stuff</label>
    <input
      name="query"
      type="text"
      id="search-input"
      queryParamName="queryText"
      #input
    >
    <button class="visually-hidden" type="submit">Accept</button>
  </form>
</div>
  1. On popup's close (OnNgDestroy) i need to delete q param from URL and clear the form.
  2. Code of destroying and definition:
  queryGroup = this.qpb.group({
    queryText: this.qpb.stringParam('q')
  });

  ngOnDestroy() {
    // ... 

    this.queryGroup.setValue({});
    this.queryGroup.remove('queryText')
  }
  1. And after many attempts it's still not working - 'q' from URL doesn't dissapear.

Probably (exactly) I'm doing something wrong. Is there an option to delete queryParams from URL? programmatically or not.
Thanks.

To be honest, mimicked methods and "emtpy-on-bottle-neck" might be tricky and unintuitive withoup deep knowledge so i assume that adding a hint to the docs would be a great idea, wouldn't it?

Yeah, definitely; I'm also not against adding synonym methods for clarity (like reset() = setValue(null)). We just need to make sure this is what we actually need.

Thanks for providing the example, I appreciate it. If the component gets destroyed you don't need to call remove in the end. Calling setValue({}) does work in general, see this example. However, in your case it doesn't work because the service gets destroyed before the last setValue call propagates, see a toy example here.

A workaround for this can be seen here, which is to manually remove the query params through the router directly:

public ngOnDestroy() {
  this.router.navigate([], {
    queryParams: {
      q: undefined,
    },
    queryParamsHandling: 'merge',
    replaceUrl: true,
  });
}

Obviously this is far from ideal, but it should at least unblock you. Given your use case I think it might make sense to have a feature on ParamGroup level to remove all managed parameters on destroy, something like

this.qpb.group({
  queryText: this.qpb.stringParam('q'),
}, {
  clearOnDestroy: true,
})

That should also be a relatively easy feature to add, I think. We could add a similary thing to remove:

this.paramGroup.remove('queryText', {
  clear: true,
});

though for your case you wouldn't actually need that, and I think this can be treated as separate features.

Would the above solution (and intermediate workaround) work for you?

@hifull I've implemented the solution described above in PR #174 now. Please let me know if this would work for you and we can merge it and create a release.

@Airblader Hello! I'm sorry about making you wait for a long time.
I had been burning with other tasks without any break for a cup of coffee before I finally came here to check you answer.
I'm very grateful that you've implemented the feature that fast.

The workaround works like a charm.
So I think your suggestion is really amazing and will cheer some devs if they're stuck one day with the same problem.

Peace!

Thanks for your suggestion and detailed explanation! This is now released in @ngqp/core@1.1.0.