1

I need to not pass in any query parameters in the URL if the value not defined. In AngularJS when some sort of parameters were passed into $resource service and its value was empty or not defined, then it was never appended to the URL string, however in Angular the Http service along with its RequestOptions object which is used to set headers and parameters behaves differently.

For example this input element:

<select class="form-control form-control-sm" formControlName="catalogCode" title="Catalog Code">
    <option value="">- Catalog Code -</option>
    <option *ngFor="let option of codes" [value]="option.code">
      {{ option.text }}
    </option>
  </select>

This updates the QueryParameters I have defined and it is used in service like this:

getOfferings(parameters: QueryParameters): Observable<Offering[]> {
    let requestOptions = new RequestOptions({
      search: {
        catalogCode: parameters.catalogCode
      }
    });

    return this.http.get(`${environment.BASE_URL}/offerings`, requestOptions)
      .map(response => response.json());
  };

If the parameters.catalogCode is populated, query runs fine and the URL looks proper: http://localhost:4200/offerings?catalogCode=CODE1, however when I select the empty option from the list, the URL will be ?catalogCode= with empty value.

My backend unfortunately does not like the empty catalogCode so I would really like to prevent that as it used to be in old Angular. Is there any proper way of clearing it?

Vaelyr
  • 2,841
  • 2
  • 21
  • 34

2 Answers2

2

You'll have to do that yourself. Which is good because you get to choose the exact behaviour you need, instead of building on the hidden opinionated falsy-behaviour of an external library.

Some ways to do this in lodash:

const search = {
  catalogCode: parameters.catalogCode
};

const requestOptions = new RequestOptions({
  // only remove undefined, my preferred option
  search: _.omitBy(search, _.isUndefined)
});

or

  // remove undefined and null (but not empty strings or the number 0)
  search: _.omitBy(search, _.isNil)

or

  // remove undefined, null, and empty string (but still not the number 0)
  search: _.omitBy(search, x => _.isNil(x) || x === '')
dbandstra
  • 1,304
  • 9
  • 10
  • Agree, just thought there would be a bit more convenient way of doing it, but that will have to do for now, thanks. – Vaelyr May 31 '17 at 07:44
0

I don't think there is a way other than to filter the values manually.

PLUNKER

//our root app component
import {Component, NgModule, VERSION} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
import {FormsModule, ReactiveFormsModule, FormBuilder} from '@angular/forms';
import {HttpModule, Http, URLSearchParams} from '@angular/http';

@Component({
  selector: 'my-app',
  template: `
<form [formGroup]="myFormGroup" (ngSubmit)="onSubmit()">
  <select class="form-control form-control-sm" formControlName="catalogCode" title="Catalog Code">
    <option value="">- Catalog Code -</option>
    <option *ngFor="let option of codes" [value]="option.code">
      {{ option.text }}
    </option>
  </select>

  <button type="submit">Submit</button>
</form>
  `,
})
export class App {

  public myFormGroup;

  public codes = [
    { code: 'option1', text: 'option 1' },
    { code: 'option2', text: 'option 2' },
    { code: 'option3', text: 'option 3' },
  ];

  constructor(private formBuilder: FormBuilder, private http: Http) {
    this.myFormGroup = formBuilder.group({
      catalogCode: ['']
    });
  }

  public onSubmit() {
    const formValue = this.myFormGroup.value;
    const params = new URLSearchParams();

    Object.keys(formValue).forEach(key => {
      const value = formValue[key];
      if(value === null || value === undefined || value === '') {
        return;
      }

      params.set(key, value); 
    });

    const url = `http://localhost:8888/test?${params.toString()}`;

    alert(url);

    this.http.get(url);
  }
}

@NgModule({
  imports: [ BrowserModule, FormsModule, ReactiveFormsModule, HttpModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}
andreim
  • 3,365
  • 23
  • 21