Skip to content

Commit

Permalink
fix(nav): create opts object when undefined/null
Browse files Browse the repository at this point in the history
Closes #5737
  • Loading branch information
adamdbradley committed Mar 6, 2016
1 parent 5863e2c commit 8975016
Show file tree
Hide file tree
Showing 14 changed files with 84 additions and 42 deletions.
4 changes: 2 additions & 2 deletions ionic/components/action-sheet/action-sheet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Animation} from '../../animations/animation';
import {Transition, TransitionOptions} from '../../transitions/transition';
import {Config} from '../../config/config';
import {Icon} from '../icon/icon';
import {isDefined} from '../../util/util';
import {isPresent} from '../../util/util';
import {NavParams} from '../nav/nav-params';
import {ViewController} from '../nav/view-controller';

Expand Down Expand Up @@ -82,7 +82,7 @@ export class ActionSheet extends ViewController {

constructor(opts: ActionSheetOptions = {}) {
opts.buttons = opts.buttons || [];
opts.enableBackdropDismiss = isDefined(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;

super(ActionSheetCmp, opts);
this.viewType = 'action-sheet';
Expand Down
10 changes: 5 additions & 5 deletions ionic/components/alert/alert.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import {NgClass, NgSwitch, NgIf, NgFor} from 'angular2/common';
import {Animation} from '../../animations/animation';
import {Transition, TransitionOptions} from '../../transitions/transition';
import {Config} from '../../config/config';
import {isDefined} from '../../util/util';
import {isPresent} from '../../util/util';
import {NavParams} from '../nav/nav-params';
import {ViewController} from '../nav/view-controller';

Expand Down Expand Up @@ -122,7 +122,7 @@ export class Alert extends ViewController {
constructor(opts: AlertOptions = {}) {
opts.inputs = opts.inputs || [];
opts.buttons = opts.buttons || [];
opts.enableBackdropDismiss = isDefined(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;
opts.enableBackdropDismiss = isPresent(opts.enableBackdropDismiss) ? !!opts.enableBackdropDismiss : true;

super(AlertCmp, opts);
this.viewType = 'alert';
Expand Down Expand Up @@ -326,9 +326,9 @@ class AlertCmp {
data.inputs = data.inputs.map((input, index) => {
return {
type: input.type || 'text',
name: isDefined(input.name) ? input.name : index,
placeholder: isDefined(input.placeholder) ? input.placeholder : '',
value: isDefined(input.value) ? input.value : '',
name: isPresent(input.name) ? input.name : index,
placeholder: isPresent(input.placeholder) ? input.placeholder : '',
value: isPresent(input.value) ? input.value : '',
label: input.label,
checked: !!input.checked,
id: 'alert-input-' + this.id + '-' + index
Expand Down
1 change: 0 additions & 1 deletion ionic/components/list/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import {Directive, ElementRef, Renderer, Attribute, NgZone} from 'angular2/core'

import {Ion} from '../ion';
import {ItemSlidingGesture} from '../item/item-sliding-gesture';
import {isDefined} from '../../util';

/**
* The List is a widely used interface element in almost any mobile app,
Expand Down
55 changes: 39 additions & 16 deletions ionic/components/nav/nav-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {IonicApp} from '../app/app';
import {Keyboard} from '../../util/keyboard';
import {NavParams} from './nav-params';
import {NavRouter} from './nav-router';
import {pascalCaseToDashCase, isTrueProperty, isUndefined} from '../../util/util';
import {pascalCaseToDashCase, isTrueProperty, isBlank} from '../../util/util';
import {raf} from '../../util/dom';
import {SwipeBackGesture} from './swipe-back';
import {Transition} from '../../transitions/transition';
Expand Down Expand Up @@ -178,7 +178,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when done
*/
setRoot(page: Type, params: any = {}, opts: NavOptions = {}): Promise<any> {
setRoot(page: Type, params?: any, opts?: NavOptions): Promise<any> {
return this.setPages([{page, params}], opts);
}

Expand Down Expand Up @@ -255,11 +255,15 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass
* @returns {Promise} Returns a promise when the pages are set
*/
setPages(pages: Array<{page: Type, params?: any}>, opts: NavOptions = {}): Promise<any> {
setPages(pages: Array<{page: Type, params?: any}>, opts?: NavOptions): Promise<any> {
if (!pages || !pages.length) {
return Promise.resolve(false);
}

if (isBlank(opts)) {
opts = {};
}

// deprecated warning
pages.forEach(pg => {
if (pg['componentType']) {
Expand Down Expand Up @@ -303,7 +307,7 @@ export class NavController extends Ion {
/**
* @private
*/
private setViews(components, opts: NavOptions = {}) {
private setViews(components, opts?: NavOptions) {
console.warn('setViews() deprecated, use setPages() instead');
return this.setPages(components, opts);
}
Expand Down Expand Up @@ -373,7 +377,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise, which resolves when the transition has completed
*/
push(page: Type, params: any = {}, opts: NavOptions = {}) {
push(page: Type, params?: any, opts?: NavOptions) {
return this.insertPages(-1, [{page: page, params: params}], opts);
}

Expand Down Expand Up @@ -402,7 +406,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise, which resolves when the transition has completed
*/
present(enteringView: ViewController, opts: NavOptions = {}): Promise<any> {
present(enteringView: ViewController, opts?: NavOptions): Promise<any> {
let rootNav = this.rootNav;

if (rootNav['_tabs']) {
Expand All @@ -412,6 +416,10 @@ export class NavController extends Ion {
return;
}

if (isBlank(opts)) {
opts = {};
}

enteringView.setNav(rootNav);

opts.keyboardClose = false;
Expand Down Expand Up @@ -454,7 +462,7 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the page has been inserted into the navigation stack
*/
insert(insertIndex: number, page: Type, params: any = {}, opts: NavOptions = {}): Promise<any> {
insert(insertIndex: number, page: Type, params?: any, opts?: NavOptions): Promise<any> {
return this.insertPages(insertIndex, [{page: page, params: params}], opts);
}

Expand Down Expand Up @@ -486,16 +494,20 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the pages have been inserted into the navigation stack
*/
insertPages(insertIndex: number, insertPages: Array<{page: Type, params?: any}>, opts: NavOptions = {}): Promise<any> {
insertPages(insertIndex: number, insertPages: Array<{page: Type, params?: any}>, opts?: NavOptions): Promise<any> {
let views = insertPages.map(p => new ViewController(p.page, p.params));
return this._insertViews(insertIndex, views, opts);
}

private _insertViews(insertIndex: number, insertViews: Array<ViewController>, opts: NavOptions = {}): Promise<any> {
private _insertViews(insertIndex: number, insertViews: Array<ViewController>, opts?: NavOptions): Promise<any> {
if (!insertViews || !insertViews.length) {
return Promise.reject('invalid pages');
}

if (isBlank(opts)) {
opts = {};
}

// insert the new page into the stack
// returns the newly created entering view
let enteringView = this._insert(insertIndex, insertViews);
Expand Down Expand Up @@ -616,16 +628,20 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion
* @returns {Promise} Returns a promise when the transition is completed
*/
pop(opts: NavOptions = {}): Promise<any> {
pop(opts?: NavOptions): Promise<any> {
// get the index of the active view
// which will become the view to be leaving
let activeView = this.getByState(STATE_TRANS_ENTER) ||
this.getByState(STATE_INIT_ENTER) ||
this.getActive();

if (isBlank(opts)) {
opts = {};
}

// if not set, by default climb up the nav controllers if
// there isn't a previous view in this nav controller
if (isUndefined(opts.climbNav)) {
if (isBlank(opts.climbNav)) {
opts.climbNav = true;
}
return this.remove(this.indexOf(activeView), 1, opts);
Expand All @@ -635,7 +651,7 @@ export class NavController extends Ion {
* Similar to `pop()`, this method let's you navigate back to the root of the stack, no matter how many views that is
* @param {object} [opts={}] Any options you want to use pass to transtion
*/
popToRoot(opts: NavOptions = {}): Promise<any> {
popToRoot(opts?: NavOptions): Promise<any> {
return this.popTo(this.first(), opts);
}

Expand All @@ -644,7 +660,7 @@ export class NavController extends Ion {
* @param {ViewController} view to pop to
* @param {object} [opts={}] Any options you want to use pass to transtion
*/
popTo(view: ViewController, opts: NavOptions = {}): Promise<any> {
popTo(view: ViewController, opts?: NavOptions): Promise<any> {
let startIndex = this.indexOf(view);
let activeView = this.getByState(STATE_TRANS_ENTER) ||
this.getByState(STATE_INIT_ENTER) ||
Expand Down Expand Up @@ -673,14 +689,18 @@ export class NavController extends Ion {
* @param {object} [opts={}] Any options you want to use pass to transtion.
* @returns {Promise} Returns a promise when the page has been removed.
*/
remove(startIndex: number = -1, removeCount: number = 1, opts: NavOptions = {}): Promise<any> {
remove(startIndex: number = -1, removeCount: number = 1, opts?: NavOptions): Promise<any> {
if (startIndex === -1) {
startIndex = this._views.length - 1;

} else if (startIndex < 0 || startIndex >= this._views.length) {
return Promise.reject("remove index out of range");
}

if (isBlank(opts)) {
opts = {};
}

// default the direction to "back"
opts.direction = opts.direction || 'back';

Expand Down Expand Up @@ -878,8 +898,11 @@ export class NavController extends Ion {
// lets time this sucker, ready go
let wtfScope = wtfStartTimeRange('NavController#_transition', (enteringView && enteringView.name));

if (this.config.get('animate') === false ||
(this._views.length === 1 && !this._init)) {
if (isBlank(opts)) {
opts = {};
}

if (this.config.get('animate') === false || (this._views.length === 1 && !this._init)) {
opts.animate = false;
}

Expand Down
8 changes: 6 additions & 2 deletions ionic/components/nav/test/basic/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MyCmpTest{}
<button ion-item (click)="setPages()">setPages() (Go to PrimaryHeaderPage)</button>
<button ion-item (click)="setRoot()">setRoot(PrimaryHeaderPage) (Go to PrimaryHeaderPage)</button>
<button ion-item (click)="nav.pop()">Pop</button>
<button ion-item (click)="viewDismiss()">View Dismiss</button>
<button ion-item (click)="quickPush()">New push during transition</button>
<button ion-item (click)="quickPop()">New pop during transition</button>
<button ion-item (click)="reload()">Reload</button>
Expand All @@ -62,8 +63,7 @@ class FirstPage {

constructor(
private nav: NavController,
app: IonicApp,
config: Config
private view: ViewController
) {
this.pushPage = FullPage;

Expand Down Expand Up @@ -110,6 +110,10 @@ class FirstPage {
}, 250);
}

viewDismiss() {
this.view.dismiss();
}

reload() {
window.location.reload();
}
Expand Down
14 changes: 14 additions & 0 deletions ionic/components/nav/test/nav-controller.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,20 @@ export function run() {

});

describe('remove', () => {

it('should create opts if passed in arg is undefined or null', () => {
let view1 = new ViewController(Page1);
view1.state = STATE_INACTIVE;
let view2 = new ViewController(Page2);
view2.state = STATE_ACTIVE;
nav._views = [view1, view2];

nav.remove(1, 1, null);
});

});

describe('_remove', () => {

it('should reassign activily transitioning leave that isnt getting removed, to become force active', () => {
Expand Down
5 changes: 3 additions & 2 deletions ionic/components/nav/view-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {Output, EventEmitter, Type, TemplateRef, ViewContainerRef, ElementRef, R
import {Navbar} from '../navbar/navbar';
import {NavController, NavOptions} from './nav-controller';
import {NavParams} from './nav-params';
import {isPresent} from '../../util/util';


/**
Expand Down Expand Up @@ -86,9 +87,9 @@ export class ViewController {
*/
@Output() private _emitter: EventEmitter<any> = new EventEmitter();

constructor(public componentType?: Type, data: any = {}) {
constructor(public componentType?: Type, data?: any) {
// passed in data could be NavParams, but all we care about is its data object
this.data = (data instanceof NavParams ? data.data : data);
this.data = (data instanceof NavParams ? data.data : isPresent(data) ? data : {});
}

subscribe(generatorOrNext?: any): any {
Expand Down
4 changes: 2 additions & 2 deletions ionic/components/option/option.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {Directive, ElementRef, Input, Output, EventEmitter} from 'angular2/core';

import {isDefined, isTrueProperty} from '../../util/util';
import {isPresent, isTrueProperty} from '../../util/util';

/**
* @name Option
Expand Down Expand Up @@ -40,7 +40,7 @@ export class Option {
*/
@Input()
get value() {
if (isDefined(this._value)) {
if (isPresent(this._value)) {
return this._value;
}
return this.text;
Expand Down
4 changes: 2 additions & 2 deletions ionic/components/radio/radio-button.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {Component, Optional, Input, Output, HostListener, EventEmitter} from 'angular2/core';

import {Form} from '../../util/form';
import {isTrueProperty, isDefined, isBlank} from '../../util/util';
import {isTrueProperty, isPresent, isBlank} from '../../util/util';
import {Item} from '../item/item';
import {ListHeader} from '../list/list';
import {RadioGroup} from './radio-group';
Expand Down Expand Up @@ -142,7 +142,7 @@ export class RadioButton {
* @private
*/
ngOnInit() {
if (this._group && isDefined(this._group.value) && this._group.value == this.value) {
if (this._group && isPresent(this._group.value) && this._group.value == this.value) {
this.checked = true;
}
}
Expand Down
2 changes: 1 addition & 1 deletion ionic/components/radio/radio-group.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {NG_VALUE_ACCESSOR} from 'angular2/common';

import {RadioButton} from './radio-button';
import {ListHeader} from '../list/list';
import {isDefined} from '../../util/util';
import {isPresent} from '../../util/util';

const RADIO_VALUE_ACCESSOR = new Provider(
NG_VALUE_ACCESSOR, {useExisting: forwardRef(() => RadioGroup), multi: true});
Expand Down
4 changes: 2 additions & 2 deletions ionic/components/searchbar/searchbar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {Ion} from '../ion';
import {Config} from '../../config/config';
import {Icon} from '../icon/icon';
import {Button} from '../button/button';
import {isDefined, debounce} from '../../util/util';
import {isPresent, debounce} from '../../util/util';


/**
Expand Down Expand Up @@ -206,7 +206,7 @@ export class Searchbar extends Ion {
ngAfterViewInit() {
// If the user passes an undefined variable to ngModel this will warn
// and set the value to an empty string
if (!isDefined(this.value)) {
if (!isPresent(this.value)) {
console.warn('Searchbar was passed an undefined value in ngModel. Please make sure the variable is defined.');
this.value = '';
this.onChange(this.value);
Expand Down
Loading

0 comments on commit 8975016

Please sign in to comment.