Is there a way to provide data when setting the rootPage in Ionic 2? I know I can provide data with the NavController like so:
this.navCtrl.push(NewPage, {
foo: bar
})
but if I want to set a new rootPage, how can I pass data?
You can set root page and pass the data like below:
this.navCtrl.setRoot(YourPage,{myData:"test data"})
then you can get this data in 'YourPage' like below:
this.navParam.get('myData')
in app.component.ts I have the following:
export class MyApp {
#ViewChild(Nav) nav: Nav;
...
so I can change the rootPage like so:
this.nav.push(NewPage, {
foo: bar
})
rather than:
this.rootPage = NewPage;
and any data passed will be available in NewPage
Pop a page off of the navigation stack:
this.navCtrl.pop();
To change the root page at any point throughout the application:
this.navCtrl.setRoot(SecondPage);
Passing Data to root page:
this.navCtrl.push(SecondPage, {
thing1: data1,
thing2: data2
});
Related
I have a PWA built with ionic deep linker. I have done a demo here https://stackblitz.com/edit/ionic-mee2ut?file=app%2Fcustomer%2Fcustomer.component.html where the browser back button doesn't work as expected.
Steps to reproduce
1.In Dashboard page click on edit button.It will navigate to customer
page(see URL.It is changed to /Customer/CustomerId).
2.In Customer page, you will see the customer info and other customers
list, there click edit from other customers list.This will open another
page.(see URL.It is changed to /Customer/CustomerId).
3.Click on browser back button u can see that the URL is changed but the
view is not updated.
If I repeat steps 1 & 2 then click on nav back button instead of browser button then it works correctly.Both the URL and the view gets updated.
Is there something I am doing wrong because the browser back button does not work as expected or this is issue of ionic framework.
This is how i navigate between views
EditCustomer(Customer: any) {
this.navCtrl.push('Customer', { Id: Customer.Id, Name: Customer.Name });
}
Can somebody please tell me a way how to resolve this issue?
I saw your code in the above url, you are passing id as param but not the name so, that is the reason url is changing but data is not reflected i modified your code in app.module.ts file please replace this code in your app.module.ts file
IonicModule.forRoot(MyApp, {}, {
links: [
{ component: DashboardComponent, name: 'Dashboard', segment: 'Dashboard' },
{ component: CustomerComponent, name: 'Customer', segment: 'Customer/:Id/:Name' }
]
})
Please replace your app.module.ts with the following code
import { Component } from '#angular/core';
import { Platform, IonicApp, App } from 'ionic-angular';
#Component({
templateUrl: 'app.html'
})
export class MyApp {
rootPage:any = 'Dashboard';
constructor(private _app: App, platform: Platform, private _ionicApp: IonicApp,) {
platform.ready().then(() => {
this.setupBackButtonBehavior();
});
}
private setupBackButtonBehavior () {
// If on web version (browser)
if (window.location.protocol !== "file:") {
// Register browser back button action(s)
window.onpopstate = (evt) => {
//Navigate back
if (this._app.getRootNav().canGoBack())
this._app.getRootNav().pop();
};
}
}
}
I was able to use something like this:
let randomID = this.makeId(5); // random string id
this.navCtrl.push('path', {
eventID: eventID,
instituteID: instituteID,
randomID: randomID
}, {
id: `path/${eventID}/${instituteID}/${randomID}`
});
This "id" seems to fix it, but if you can go to the same page, then it requires a "random" value to separate each visit to that page.
#IonicPage({
name: 'path',
segment: 'path/:instituteID/:eventID/:randomID'
})
It looks like, by default, it uses the name of the page as an id for that view. If multiple views have same id => issue when using browser back/forward. That's where the random comes in, to separate multiple instances of the same page.
I have an application made with Ionic 2, The work flow is like this
Case A . When user is using app for the first time
User Logs in (loading is shown)
When successfully logged in loading window is hidden and user is forwarded to Dashboard page.
In dashboard page items are loaded via ajax request.
Case B. When user is already logged in before
The first screen is Dashboard and items are loaded via ajax request.
Problem
In case A, when user logs in and forwarded to DashboardPage, the loading screen doesn't gets dismissed. Sometimes it gets dismissed but most of the time it doesnot? Is this an ionic bug or am I doing something wrong??
Here is my DashboardPage
//imports here
export class DashboardPage {
public loadingmsg: any;
public ajaxRequest: any;
constructor(
public navCtrl: NavController,
public navParams: NavParams,
private webservice: WebService,
private loadingCtrl: LoadingController
)
{
this.loadDashboardContents();
}
loadDashboardContents(){
//other codes
this.loadingmsg = this.loadingCtrl.create({
content:"Loading contents, please wait..."
});
this.loadingmsg.present();
this.ajaxRequest = this.webservice.getDashboardContents(params).subscribe(data => {
this.loadingmsg.dismiss().then(()=>{
//other codes to save retrieved data to localstorage.
});
});
}
}
UPDATE
The login method from login page
loginUser(){
this.loading=this.loadingctrl.create({
content:"Logging in, please wait..."
});
this.loading.present();
this.ajaxRequest = this.webservice.loginUser(params).subscribe(data => {
this.loading.dismiss();
if(data.status =="ok"){
this.navctrl.push(DashboardPage).then(()=>{
const index = this.viewCtrl.index;
this.navctrl.remove(index);
});
}else{
//show error alert
}
}, err =>{
this.loading.dismiss();
});
}
My Ionic and cordova version information
Ionic Framework: 3.5.0
Ionic App Scripts: 1.3.9
Angular Core: 4.1.3
Angular Compiler CLI: 4.1.3
Node: 6.10.3
OS Platform: Windows 10
Cordova Version: 6.5.0
I am currently using loading in my project and it works well in all case. To ensure loading will always dismiss you need to add some code:
1. duration, dismissOnPageChange
let loading = this.loadingCtrl.create({
content: "",
duration: 5000, //ms
dismissOnPageChange: true
})
2. dissmis when ajax call success or error:
.subscribe(success=>{
//some code
loading.dismiss();
},error=>{
//some code
loading.dismiss();
})
It may be due to the this reference inside your subscribe method. I would try declaring loadingmsg locally and removing this.
loadDashboardContents(){
//other codes
let loadingmsg = this.loadingCtrl.create({
content:"Loading contents, please wait..."
});
loadingmsg.present();
this.ajaxRequest = this.webservice.getDashboardContents(params).subscribe(data => {
loadingmsg.dismiss().then(()=>{
//other codes to save retrieved data to localstorage.
});
});
}
I'm using ng2-charts in my ionic 2 project to draw a line chart. I need to access the chart datapoint collection in the (chartClick) event. For that I need access to the base chart.js object for the chart. Is there a way I can access the chart object?
HTML:
<base-chart class="chart"
[data]="chartData"
[labels]="chartLabels"
[options]="lineChartOptions"
[colours]="lineChartColours"
[legend]="lineChartLegend"
[chartType]="chartType"
(chartClick)="chartClicked($event)"></base-chart>
TypeScript:
chartClicked(e: any) {
var chart = //reference to base chart object.
var points = chart.getPointsAtEvent(e);
alert(chart.datasets[0].points.indexOf(points[0]));
}
Managed to solve this eventually. Used the app.getComponent() method to get a reference to the ng2-chart object and then to the internal chart.js chart object.
HTML: (added the element id 'mylinechart')
<base-chart id="mylinechart" class="chart"
[data]="chartData"
[labels]="chartLabels"
[options]="lineChartOptions"
[colours]="lineChartColours"
[legend]="lineChartLegend"
[chartType]="chartType"
(chartClick)="chartClicked($event)"></base-chart>
Typescript:
constructor(private app: IonicApp) {
}
chartClicked(e: any) {
var chartComponent = this.app.getComponent('mylinechart'); //ng2-chart object
var chart = chartComponent.chart; //Internal chart.js chart object
console.log(chart.datasets[0].points.indexOf(e.activePoints[0]));
}
Update on 14-Feb-2017 with #ViewChild
If the above doesn't work (due to angular updates) try this. I didn't test this exact code as I don't have the exact source code anymore. In my current project I'm using angular 2.4 so I know #ViewChild works.
Change the HTML markup to:
<base-chart #mylinechart class="chart" etc.. (notice #mylinechart)
Type script:
At the top: import { Component, ViewChild } from '#angular/core';
And then inside your component class:
#ViewChild('mylinechart')
private chartComponent: any;
constructor(private app: IonicApp) {
}
chartClicked(e: any) {
var chart = this.chartComponent.chart; //Internal chart.js chart object
console.log(chart.datasets[0].points.indexOf(e.activePoints[0]));
}
Basically #ViewChild gets you a reference to the component marked by '#mylinechart' in the template. Decorating the chartComponent variable with #ViewChild makes it possible to access the chart component via that variable. Please note that references returned by #ViewChild are only available after 'ngAfterViewInit' life-cycle event. Since my use case is a chart 'click' event, I can safely assume that the view has been initialized by that time.
Reference: Angular #ViewChild
I see this question is being ask all over again still don't find solution that works for such a trivial task.
This url displays a list of navigations tabs for workspaces.
http://localhost:4200/users/1/workspaces
Each of tab resolves to
http://localhost:4200/users/1/workspaces/:wid
Also on the I have a button that suppose to create a new workspace as well as new tab.
Here how controller for looks:
export default Ember.Controller.extend({
actions: {
newWorkspace: function () {
this.get('currentModel').reload();
var self = this;
var onFail = function() {
// deal with the failure here
};
var onSuccess = function(workspace) {
self.transitionToRoute('dashboard.workspaces.workspace', workspace.id);
};
this.store.createRecord('workspace', {
title: 'Rails is Omakase'
}).save().then(onSuccess, onFail);
}
}
});
When I click on button I see in ember inspector new record indeed created as well as url redirected to id that represents newly created workspace.
My question is how to force model/template to reload. I have already killed 5h trying model.reload() etc. Everything seem not supported no longer. Please please help.
UPDATE
When adding onSuccess
model.pushObject(post);
throws Uncaught TypeError: internalModel.getRecord is not a function
I believe you should call this.store.find('workspace', workspace.id) for Ember Data 1.12.x or earlier. For 1.13 and 2.0 there are more complicated hooks that determine whether or not the browser should query the server again or use a cached value; in that case, call this.store.findRecord('workspace', workspace.id, { reload: true }).
I do not know if this help. I had a similar problem. My action was performed in the route. Refresh function took care of everything.
I'm trying to display a simple template, but it seems like the template doesn't get added, as there is nothing added to the DOM. The code is called for sure and a container has the method setTpl(tpl). What am I doing wrong? The sample above is the most simple example I could imagine, but it doesn't work!
Ext.define('MyApp.view.sample', {
extend: 'Ext.Container'
config: {},
initialize: function() {
this.callParent();
var sampleText = '<div> why?? </div>';
var t = new Ext.Template(
sampleText,
{
compiled: true
}
);
t.compile();
this.setTpl(t);
},
});
HTML = template + data. So your next step is to call setData. Check the docs for tpl. If what you want is to plug in some raw HTML that doesn't depend on data, you've got the html config (and the corollary method setHTML). Last advice, if that's just for rendering some HTML, you don't need to use a container, a Component would be enough.
You have created a class, but you also need to instantiate it. Try something like this:
Ext.create('MyApp.view.sample', {
renderTo: 'some-div-id',
// any other necessary config options
// (see http://docs.sencha.com/extjs/3.4.0/#!/api/Ext.Container)
});