Incase anyone was wondering how to do this, I've written an extension that should work with c# .Net Core 1.1 and Typescript 2.2.2 WebApi which looks like so.
Remember to include these two imports where you are using it as well
import { URLSearchParams } from '@angular/http';
import 'rxjs/add/operator/map'
export class QueryStringBuilder {
static BuildParametersFromSearch<T>(obj: T): URLSearchParams {
let params: URLSearchParams = new URLSearchParams();
if (obj == null)
{
return params;
}
QueryStringBuilder.PopulateSearchParams(params, '', obj);
return params;
}
private static PopulateArray<T>(params: URLSearchParams, prefix: string, val: Array<T>) {
for (let index in val) {
let key = prefix + '[' + index + ']';
let value: any = val[index];
QueryStringBuilder.PopulateSearchParams(params, key, value);
}
}
private static PopulateObject<T>(params: URLSearchParams, prefix: string, val: T) {
const objectKeys = Object.keys(val) as Array<keyof T>;
if (prefix) {
prefix = prefix + '.';
}
for (let objKey of objectKeys) {
let value = val[objKey];
let key = prefix + objKey;
QueryStringBuilder.PopulateSearchParams(params, key, value);
}
}
private static PopulateSearchParams<T>(params: URLSearchParams, key: string, value: any) {
if (value instanceof Array) {
QueryStringBuilder.PopulateArray(params, key, value);
}
else if (value instanceof Date) {
params.set(key, value.toISOString());
}
else if (value instanceof Object) {
QueryStringBuilder.PopulateObject(params, key, value);
}
else {
params.set(key, value.toString());
}
}
}
This is working for all the complex types I've used so far.
EDIT Usage I've included all of the import statements I believe the important ones are RequestOptionsArgs, RequestOptions, but I remembered their required so just incase I've included them all.
import { Injectable } from '@angular/core';
import { Http, Headers, RequestOptionsArgs, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';
import { IHasId } from '../interfaces/interfaces';
import 'rxjs/add/operator/map';
import { QueryOptions, IFilterNode } from "../models/queryOptions";
import { QueryStringBuilder } from "../models/QueryStringBuilder";
import 'rxjs/add/operator/map'
@Injectable()
export class ProviderBase<T extends IHasId> {
getList(filterParams?: IFilterNode): Observable<T[]> {
var searchParams = QueryStringBuilder.BuildParametersFromSearch(filterParams);
let requestArguments: RequestOptionsArgs = new RequestOptions({ search: searchParams });
return this.http.get(`${this.apiUrl}/${this.route}`, requestArguments).map(res => <T[]>res.json());
}
}