Skip to content

Commit

Permalink
Merge pull request #128 from TNG/feature-117-3
Browse files Browse the repository at this point in the history
#117: Strict TypeScript mode
  • Loading branch information
Airblader authored Mar 31, 2019
2 parents c762650 + c3c0c54 commit 768516c
Show file tree
Hide file tree
Showing 17 changed files with 91 additions and 69 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export class MultiSelectControlValueAccessorDirective<T> implements ControlValue
this.selectedIds = Array.from(this.options.entries())
.filter(([id, option]) => option.selected)
.map(([id]) => id);
const values = this.selectedIds.map(id => this.optionMap.get(id));
const values = this.selectedIds.map(id => this.optionMap.get(id)!);
this.fnChange(values);
}

Expand All @@ -49,7 +49,7 @@ export class MultiSelectControlValueAccessorDirective<T> implements ControlValue

this.selectedIds = values
.map(value => this.getOptionId(value))
.filter(id => id !== null);
.filter((id: string | null): id is string => id !== null);
this.options.forEach((option, id) => option.selected = this.selectedIds.includes(id));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ export class MultiSelectOptionDirective<T> implements OnInit, OnDestroy {

public ngOnDestroy() {
if (this.parent) {
this.parent.deregisterOption(this.id);
this.parent.deregisterOption(this.id!);
}
}

@Input('value')
public set value(value: T) {
if (this.parent) {
this.parent.updateOptionValue(this.id, value);
this.parent.updateOptionValue(this.id!, value);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const NGQP_NUMBER_VALUE_ACCESSOR: any = {
})
export class NumberControlValueAccessorDirective implements ControlValueAccessor {

private fnChange = (_: number) => {};
private fnChange = (_: number | null) => {};
private fnTouched = () => {};

@HostListener('input', ['$event'])
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ export const NGQP_RANGE_VALUE_ACCESSOR: any = {
})
export class RangeControlValueAccessorDirective implements ControlValueAccessor {

private fnChange = (_: number) => {};
private fnChange = (_: number | null) => {};
private fnTouched = () => {};

@HostListener('input', ['$event'])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Directive, ElementRef, forwardRef, HostListener, Renderer2, StaticProvider } from '@angular/core';
import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';
import { undefinedToNull } from '../util';

/** @ignore */
export const NGQP_SELECT_VALUE_ACCESSOR: StaticProvider = {
Expand All @@ -20,13 +21,13 @@ export class SelectControlValueAccessorDirective<T> implements ControlValueAcces
private optionMap = new Map<string, T>();

private idCounter = 0;
private fnChange = (_: T) => {};
private fnChange = (_: T | null) => {};
private fnTouched = () => {};

@HostListener('change', ['$event'])
public onChange(event: UIEvent) {
this.selectedId = (event.target as HTMLOptionElement).value;
this.value = this.optionMap.get(this.selectedId);
this.value = undefinedToNull(this.optionMap.get(this.selectedId));
this.fnChange(this.value);
}

Expand All @@ -38,10 +39,10 @@ export class SelectControlValueAccessorDirective<T> implements ControlValueAcces
constructor(private renderer: Renderer2, private elementRef: ElementRef<HTMLSelectElement>) {
}

public writeValue(value: T) {
public writeValue(value: T | null) {
this.value = value;

this.selectedId = this.getOptionId(value);
this.selectedId = value === null ? null : this.getOptionId(value);
if (this.selectedId === null) {
this.renderer.setProperty(this.elementRef.nativeElement, 'selectedIndex', -1);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,15 @@ export class SelectOptionDirective<T> implements OnInit, OnDestroy {

public ngOnDestroy() {
if (this.parent) {
this.parent.deregisterOption(this.id);
this.parent.deregisterOption(this.id!);
this.parent.writeValue(this.parent.value);
}
}

@Input('value')
public set value(value: T) {
if (this.parent) {
this.parent.updateOptionValue(this.id, value);
this.parent.updateOptionValue(this.id!, value);
this.parent.writeValue(this.parent.value);
}
}
Expand Down
4 changes: 2 additions & 2 deletions projects/ngqp/core/src/lib/accessors/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ import { NGQP_BUILT_IN_ACCESSORS } from './ngqp-accessors';
*
* @internal
*/
export function selectValueAccessor(valueAccessors: ControlValueAccessor[]): ControlValueAccessor | null {
export function selectValueAccessor(valueAccessors: ControlValueAccessor[]): ControlValueAccessor {
if (!valueAccessors || !Array.isArray(valueAccessors)) {
return null;
throw new Error(`No matching ControlValueAccessor has been found for this form control`);
}

let defaultAccessor: ControlValueAccessor | null = null;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export class QueryParamGroupDirective implements OnChanges {
* The {@link QueryParamGroup} to bind.
*/
@Input('queryParamGroup')
public queryParamGroup: QueryParamGroup;
public queryParamGroup: QueryParamGroup | null = null;

/** @internal */
constructor(private groupService: QueryParamGroupService) {
Expand Down
40 changes: 26 additions & 14 deletions projects/ngqp/core/src/lib/directives/query-param-group.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class NavigationData {
export class QueryParamGroupService implements OnDestroy {

/** The {@link QueryParamGroup} to bind. */
private queryParamGroup: QueryParamGroup;
private queryParamGroup: QueryParamGroup | null = null;

/** List of {@link QueryParamAccessor} registered to this service. */
private directives = new Map<string, QueryParamAccessor[]>();
Expand Down Expand Up @@ -122,7 +122,7 @@ export class QueryParamGroupService implements OnDestroy {
})
).pipe(
// Do not synchronize while the param is detached from the group
filter(() => !!this.queryParamGroup.get(queryParamName)),
filter(() => !!this.getQueryParamGroup().get(queryParamName)),
map((newValue: unknown[]) => this.getParamsForValue(partitionedQueryParam, partitionedQueryParam.reduce(newValue))),
takeUntil(this.destroy$),
).subscribe(params => this.enqueueNavigation(new NavigationData(params)));
Expand Down Expand Up @@ -154,7 +154,7 @@ export class QueryParamGroupService implements OnDestroy {
});

this.directives.delete(queryParamName);
const queryParam = this.queryParamGroup.get(queryParamName);
const queryParam = this.getQueryParamGroup().get(queryParamName);
if (queryParam) {
queryParam._clearChangeFunctions();
}
Expand All @@ -170,10 +170,14 @@ export class QueryParamGroupService implements OnDestroy {

/** Listens for programmatic changes on group level and synchronizes to the router. */
private setupGroupChangeListener(): void {
this.queryParamGroup._registerOnChange((newValue: Record<string, unknown>) => {
this.getQueryParamGroup()._registerOnChange((newValue: Record<string, unknown> | null) => {
if (newValue === null) {
throw new Error(`Received null value from QueryParamGroup.`);
}

let params: Params = {};
Object.keys(newValue).forEach(queryParamName => {
const queryParam = this.queryParamGroup.get(queryParamName);
const queryParam = this.getQueryParamGroup().get(queryParamName);
if (isMissing(queryParam)) {
return;
}
Expand All @@ -187,12 +191,12 @@ export class QueryParamGroupService implements OnDestroy {

/** Listens for programmatic changes on parameter level and synchronizes to the router. */
private setupParamChangeListeners(): void {
Object.keys(this.queryParamGroup.queryParams)
Object.keys(this.getQueryParamGroup().queryParams)
.forEach(queryParamName => this.setupParamChangeListener(queryParamName));
}

private setupParamChangeListener(queryParamName: string): void {
const queryParam = this.queryParamGroup.get(queryParamName);
const queryParam = this.getQueryParamGroup().get(queryParamName);
if (!queryParam) {
throw new Error(`No param in group found for name ${queryParamName}`);
}
Expand All @@ -211,7 +215,7 @@ export class QueryParamGroupService implements OnDestroy {
// particular group; however, we do need to react if one of our parameters has
// vanished when it was set before.
distinctUntilChanged((previousMap, currentMap) => {
const keys = Object.values(this.queryParamGroup.queryParams)
const keys = Object.values(this.getQueryParamGroup().queryParams)
.map(queryParam => this.wrapIntoPartition(queryParam))
.map(partitionedQueryParam => partitionedQueryParam.queryParams.map(queryParam => queryParam.urlParam))
.reduce((a, b) => [...a, ...b], []);
Expand All @@ -227,9 +231,9 @@ export class QueryParamGroupService implements OnDestroy {
const synthetic = this.isSyntheticNavigation();
const groupValue: Record<string, unknown> = {};

Object.keys(this.queryParamGroup.queryParams).forEach(queryParamName => {
Object.keys(this.getQueryParamGroup().queryParams).forEach(queryParamName => {
const partitionedQueryParam = this.getQueryParamAsPartition(queryParamName);
const newValues = partitionedQueryParam.queryParams.map(queryParam => isMultiQueryParam(queryParam)
const newValues = partitionedQueryParam.queryParams.map(queryParam => isMultiQueryParam<unknown>(queryParam)
? queryParam.deserializeValue(queryParamMap.getAll(queryParam.urlParam))
: queryParam.deserializeValue(queryParamMap.get(queryParam.urlParam))
);
Expand All @@ -243,7 +247,7 @@ export class QueryParamGroupService implements OnDestroy {
groupValue[ queryParamName ] = newValue;
});

this.queryParamGroup.setValue(groupValue, {
this.getQueryParamGroup().setValue(groupValue, {
emitEvent: !synthetic,
emitModelToViewChange: false,
});
Expand All @@ -252,7 +256,7 @@ export class QueryParamGroupService implements OnDestroy {

/** Listens for newly added parameters and starts synchronization for them. */
private watchNewParams(): void {
this.queryParamGroup.queryParamAdded$.pipe(
this.getQueryParamGroup().queryParamAdded$.pipe(
takeUntil(this.destroy$)
).subscribe(queryParamName => {
this.setupParamChangeListener(queryParamName);
Expand Down Expand Up @@ -342,7 +346,7 @@ export class QueryParamGroupService implements OnDestroy {
* This merges the global configuration with the group specific configuration.
*/
private get routerOptions(): RouterOptions {
const groupOptions = this.queryParamGroup ? this.queryParamGroup.routerOptions : {};
const groupOptions = this.getQueryParamGroup().routerOptions;

return {
...(this.globalRouterOptions || {}),
Expand All @@ -358,7 +362,7 @@ export class QueryParamGroupService implements OnDestroy {
* query parameters independent of whether they are partitioned.
*/
private getQueryParamAsPartition(queryParamName: string): PartitionedQueryParam<unknown> {
const queryParam = this.queryParamGroup.get(queryParamName);
const queryParam = this.getQueryParamGroup().get(queryParamName);
if (!queryParam) {
throw new Error(`Could not find query param with name ${queryParamName}. Did you forget to add it to your QueryParamGroup?`);
}
Expand All @@ -382,4 +386,12 @@ export class QueryParamGroupService implements OnDestroy {
});
}

private getQueryParamGroup(): QueryParamGroup {
if (!this.queryParamGroup) {
throw new Error(`No QueryParamGroup has been registered yet.`);
}

return this.queryParamGroup;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,22 @@ export class QueryParamNameDirective implements QueryParamAccessor, OnChanges, O
* Note that this does not refer to the [parameter name]{@link QueryParam#urlParam}.
*/
@Input('queryParamName')
public name: string;
public set name(name: string) {
this._name = name;
}

public get name(): string {
if (!this._name) {
throw new Error(`No queryParamName has been specified.`);
}

return this._name;
}

/** @internal */
public valueAccessor: ControlValueAccessor | null = null;
public valueAccessor: ControlValueAccessor;

private _name: string | null = null;

/** @internal */
constructor(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,13 +23,13 @@ export class QueryParamDirective implements QueryParamAccessor, OnChanges, OnDes
* The {@link QueryParam} to bind to the host component.
*/
@Input('queryParam')
public queryParam: QueryParam<unknown>;
public queryParam: QueryParam<unknown> | null = null;

/** @internal */
public readonly name = 'param';

/** @internal */
public valueAccessor: ControlValueAccessor | null = null;
public valueAccessor: ControlValueAccessor;

/** @internal */
private group = new QueryParamGroup({});
Expand Down
6 changes: 3 additions & 3 deletions projects/ngqp/core/src/lib/model/query-param-opts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export interface QueryParamOptsBase<U, T> {
* to the form control. Vice versa, if the form control takes on this value,
* the URL parameter will be removed.
*/
emptyOn?: T;
emptyOn?: T | null;

/**
* The comparator to be used with {@link QueryParamOpts#emptyOn}.
Expand All @@ -64,13 +64,13 @@ export interface QueryParamOptsBase<U, T> {
}

/** See {@link QueryParamOpts}. */
export interface QueryParamOpts<T> extends QueryParamOptsBase<T, T> {
export interface QueryParamOpts<T> extends QueryParamOptsBase<T | null, T | null> {
/** See {@link MultiQueryParamOpts}. */
multi?: false;
}

/** See {@link QueryParamOpts}. */
export interface MultiQueryParamOpts<T> extends QueryParamOptsBase<T, T[]> {
export interface MultiQueryParamOpts<T> extends QueryParamOptsBase<T | null, (T | null)[]> {
/**
* Whether this parameter can take on multiple values at once.
*
Expand Down
Loading

0 comments on commit 768516c

Please sign in to comment.