Ionic2 ngOnInit, ionViewWillEnter, and nav-push - ionic2

I have this case where navigating by a [nav-push] from a ion-item to a details page, on the details page ionViewWillEnter is not invoked, while the ngOnInit does.
//ion-item on list page...
<button ion-item detail-push
*ngFor="let recipe of recipes"
[navPush]="recipeEditPage"
[navParams]="{recipe:recipe}">
<h2>{{recipe.title}}</h2>
</button>
//details page, ionWillEnter doesn't fire, white ngOnInit does.
ngOnInit(){
if(this.navParams.data.recipe){
this._mode = RecipeEditPage.Modes.EDIT;
this._recipe=this.navParams.data.recipe;
}
else
this._recipe = this.recipeSrv.getNewRecipe();
}
Thanks! F.

Related

What happens in reloading but not in navigation in angular?

I am working in angular-9 , there are many things which works on reloading, but not after navigation. eg: there are two components A and B. and another component c have a reveal modal code(in foundation).
c component is to be included in both A and B.from component A through navigation I can move to component B which is a another page.
c.ts:
import { FormControl, Validators, FormBuilder,FormGroup, FormGroupDirective } from '#angular/forms';
loginFormControl:FormGroup;
ngOnInit() {
$('#loginModal').foundation();
this.loginFormControl = this.formBuilder.group({
phone_number: ''
});
}
c.html
<div class="reveal" id="loginModal" data-reveal>
<form class="loginForm" [formGroup]="loginFormControl"
(ngSubmit)="onSubmit()">
<input placeholder="Enter Mobile Number" formControlName="phone_number">
<button type="submit" class="button">LOGIN</button>
</form>
<button class="close-button" data-close aria-label="Close modal" type="button">
<span aria-hidden="true">×</span>
</button>
</div>
If I open the modal 'c' in both of the pages A and B on a click of two buttons on both pages with $('#loginModal').foundation('open'); in A.ts and B.ts files, it results me with some unexpected behavior.
1. the modal is open in both the pages. no issue related to view
2. But events of that modal(click,change) or if I enter phone number, It doesn't accept it from user. Even there no event works in a page until i refresh or reload the page.
3. After refreshing a page it will work on that page (including all
events and inputs), there won't be any issue in that page after reloading. but as i navigate to another component B, then it's(c) events and input won't work until i refresh this page too. this same will happen again with component A.
I haven't reach at any solution of this till now and why is this happening. Please let me know if anyone have solution of my problem. It would be fruitful for me.

Ionic 3 Tabs on Modal

I have implemented tabs on a modal.
Here is the code:
Pagewithmodal.ts
getFoodInfo(food) {
let foodModal = this.modalCtrl.create('TabspagePage', { Model: food, Api: this.api, Title: 'Food Infopedia' });
foodModal.onDidDismiss(option => {
console.log(option);
});
foodModal.present();
}
TabspagePage.html
<ion-tabs>
<ion-tab tabIcon="heart" [root]="tabNutri" tabTitle="Nutritional" [rootParams]="model"></ion-tab>
<ion-tab tabIcon="star" [root]="tabIngre" tabTitle="Ingredients" [rootParams]="model"></ion-tab>
</ion-tabs>
TabspagePage.ts
this.tabIngre = 'IngreinfoPage';
this.tabNutri = 'FoodinfoPage';
this.model = { 'Api': navParams.data.Api, 'Model': navParams.data.Model };
IngreinfoPage.html
<ion-header>
<ion-navbar color="header">
<ion-title>Food Infopedia</ion-title>
<ion-buttons end>
<button ion-button color="light" clear icon-only (click)="dismiss()">
<ion-icon name='close' is-active="true"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
IngreinfoPage.ts
dismiss() {
this.viewCtrl.dismiss();
}
When I click the close button, dismiss() function is called, and i'm getting an error Runtime Error
Uncaught (in promise): navigation stack needs at least one root page
<ion-tab tabIcon="star" [root]="tabIngre" tabTitle="Ingredients" [rootParams]="model"></ion-tab>
This will create a new nav stack with root page as your modal page: IngreinfoPage.
And when you dismiss from IngreinfoPage,it will remove only IngreinfoPage and the stack will have no root page.
If you want to dismiss the tabs modal, you will have to dismiss from the TabspagePage i.e. create a dismiss function in TabsPagePage and maybe use Events API to call the function on close.

Navigated automatically to wrong page after clicking in a button

I am newbie in ionic2, I have made a list of events with sliding Edit and Delete buttons. I have wanted to view the event details page by tapping on the row and it works fine. But if I tap on the edit button, the edit page appears and immediately replaced by event detail page. My code is following:
<ion-list>
<ion-item-sliding *ngFor="let event of eventList" (click)='goToEventDetail(event.id)'>
<ion-item><p><strong>{{event?.eventName}}</strong><p>
<p>Place: <strong>{{event?.place}}</strong></p>
<p>Date: <strong >{{event?.date}}</strong></p>
</ion-item>
<ion-item-options>
<button ion-button color="primary" (click)="goToEditEventDetail(event.id)"><ion-icon name='clipboard'></ion-icon> Edit</button>
<button ion-button color="danger" (click)="removeEvent(event.id)"><ion-icon name='trash'></ion-icon> Delete</button>
</ion-item-options>
</ion-item-sliding >
I have tried by removing "(click)='goToEventDetail(event.id)" event from "ion-item-sliding", in that case I have got expected result. My finding is, after clicking to edit button it fires "goToEditEventDetail" event and after that it also fires "goToEventDetail". I need to stop firing the second event, is there any solution? Thanks in advance.

Check a radio button in an Angular unit test

I have a component in Angular with this HTML:
<div class="row">
<label for="tipo" class="column">Tipo: </label>
<div *ngFor="let tipo of tipos" class="column">
<input type="radio" name="tipo" [value]="tipo.id"
[(ngModel)]="movimiento.tipo" (ngModelChange)="alCambiarTipo()">
<span class="{{tipo.texto | lowercase}}">{{ tipo.texto }}</span>
</div>
</div>
It has two radio buttons, and on change it triggers a function in my component. In my test I want to check the second radio button to test that my function is called. I've tried this code but It's not working:
it('should call alCambiarTipo on radio button change', () => {
spyOn(component, 'alCambiarTipo').and.callThrough();
let options: DebugElement[] = fixture.debugElement.queryAll(By.css('input[type="radio"]'));
let secondOption: HTMLInputElement = options[1].nativeElement;
secondOption.checked = true;
expect(component.alCambiarTipo).toHaveBeenCalled();
});
I've also tried using .click() on the input and it's also not working. What can I do to trigger my function? Thanks.
PS: I've also tried to change the model adding component.movimiento.tipo = 1; and calling fixture.detectChanges() and it's also not working.
The answer from #maxisam is correct, additionally you could use:
inputElement.nativeElement.dispatchEvent(new Event('change'));
If you want more compact form :)
Because you use a wrong event. It should be change event.
options[1].triggerEventHandler('change', { target: options[1].nativeElement });
You don't even need to set check

Ionic 2 ionChange event fires before event is complete

I'm struggling with putting a map on a second segment. It's a typical problem, and I've found several solutions, but they don't work for me because the events seem to get fired before the segment is build completely. I don't know if this is because of a breaking change in Ionic, or because I am doing it wrong.
page.html:
<ion-toolbar>
<ion-segment [(ngModel)]="view" (ionChange)="changeSegment()">
<ion-segment-button value="list">
<ion-icon name="list-box" isActive="false"></ion-icon>
</ion-segment-button>
<ion-segment-button value="map" (ionSelect)="selectMap()">
<ion-icon name="map" isActive="false"></ion-icon>
</ion-segment-button>
</ion-segment>
</ion-toolbar>
<ion-content [ngSwitch]="view">
<div *ngSwitchCase="'list'"></div>
<div *ngSwitchCase="'map'">
<div id='map'>Here the map comes.</div>
</div>
</ion-content>
page.js:
import {Component} from "#angular/core";
#Component({
templateUrl: 'build/pages/page/page.html'
})
export class Timeline {
constructor() {
this.view = "list";
this.selectMap = function() {
console.log("selectMap:", document.getElementById("map"));
}
this.changeSegment = function() {
console.log("changeSegment:", document.getElementById("map"));
}
}
}
(Yeah, that project is using JavaScript, not TypeScript.)
With both the change and the select events, on first click they return "null" for the map element, and only on a second click they return the correct element.
To me it looks like the events are fired before the segment is complete. (But I may just as well be making a stupid beginners mistake...)
How do I know when the #map element is available?