How to dynamically go to previous page (ionic 4)? - ionic4

Currently im migrating my ionic 3 project to ionic 5, in ionic 3 we use this.navCtrl.getPrevious().name;
to get the previous page name by getting the previous page name i will navigate to different pages based on the previous page name can you please help me how can i get previous page name in ionic 4

Ionic 4+ moved away from navCtrl and leverages Angular Router.
To read previous URL (route) you may do it via PreviousRouteService:
import { Injectable } from '#angular/core';
import { Router, RoutesRecognized } from '#angular/router';
import { filter, pairwise } from 'rxjs/operators';
#Injectable({
providedIn: "root"
})
export class PreviousRouteService {
private previousUrl: string;
private currentUrl: string;
constructor(private router: Router) {
this.currentUrl = this.router.url;
this.previousUrl = null;
this.router.events
.pipe(filter((event: any) => event instanceof RoutesRecognized), pairwise())
.subscribe((events: RoutesRecognized[]) => {
this.previousUrl = events[0].urlAfterRedirects;
this.currentUrl = events[1].urlAfterRedirects;
});
}
public getPreviousUrl() {
return this.previousUrl;
}
};
The service imports Router and tracks changes so that any component that needs previous URL information can import this service and access previous route:
constructor(
private previousRouteService: PreviousRouteService
) {}
const prevUrl = this.previousRouteService.getPreviousUrl();

Related

Vue 3 get current application instance

How to access to current instance of application inside a component?
Option 1: Create a plugin
// define a plugin
const key = "__CURRENT_APP__"
export const ProvideAppPlugin = {
install(app, options) {
app.provide(key, app)
}
}
export function useCurrentApp() {
return inject(key)
}
// when create app use the plugin
createApp().use(ProvideAppPlugin)
// get app instance in Component.vue
const app = useCurrentApp()
return () => h(app.version)
Option 2: use the internal api getCurrentInstance
import { getCurrentInstance } from "vue"
export function useCurrentApp() {
return getCurrentInstance().appContext.app
}
// in Component.vue
const app = useCurrentApp()
In Vue.js version 3, you can access the current instance of an application inside a component using the getCurrentInstance() function provided by the Composition API.
Here's an example:
import { getCurrentInstance } from 'vue'
export default {
mounted() {
const app = getCurrentInstance()
console.log(app.appContext.app) // This will log the current instance of the application
}
}
Note that getCurrentInstance() should only be used in very specific situations where it's necessary to access the instance. In general, it's recommended to use the Composition API's reactive properties and methods to manage state and actions inside a component.

Ionic 4 Not support Events?

Im using Event fucntion to publish some data in app. But its not working in ionic 4. I need to know ionic 4 support Events or not?
import { Events } from '#ionic-angular';
// Module not found: Error: Can't resolve '#ionic-angular'
You can use #angular/Events
//MyEvents Service Page
import { Injectable } from '#angular/core';
import { Subject, Observable } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class EventsService {
constructor() { }
private subject = new Subject<any>();
sendMessage(text){
this.subject.next(text);
}
getMessage():Observable<any>{
return this.subject.asObservable();
}
}
//Page for sendMessage
constructor(private events: EventsService) {
this.events.sendMessage({'created':1}); //send message key-value format
}
//Page for getMessage
subscription: Subscription;
constructor(private events: EventsService) {
this.subscription = this.events.getMessage().subscribe(text => {
console.log(text.created);
})
}
Below solution is working in ionic v4
import { Events } from '#ionic/angular';
constructor(private events: Events) {
events.subscribe('notificationLength', notilen => {
//TO DO`enter code here`
})
}
// Publish the events where ever you want
this.events.publish('notificationLength', this.NotificationList.length)
The problem was in the version. When I updated to the latest patch of version 4, it was working.
npm i #ionic/angular#4.11.10

Ionic v4 `menuController.enable` method not working on first page loaded

I use a sidemenu project with ionic v4-beta3
I want to disable sidemenu on some pages, /login for example.
It's working properly when i load /home page first then i navigate to /login page. Sidemenu desapear as expected.
When i reload my application on /login page, menu is not disabled.
import { Component, OnInit } from '#angular/core';
import { MenuController } from '#ionic/angular';
#Component({
selector: 'app-login',
templateUrl: './login.page.html',
styleUrls: ['./login.page.scss'],
})
export class LoginPage implements OnInit {
constructor(
private menuController: MenuController
) {}
ngOnInit() {}
ionViewWillEnter() {
console.log('ionViewWillEnter');
this.menuController.enable(false);
}
ionViewDidLeave() {
console.log('ionViewDidLeave');
this.menuController.enable(true);
}
}
If a use a setTimeout of 100 or 200 ms to call enable method, side menu desapears but it's not very clean...
ionViewWillEnter() {
console.log('ionViewWillEnter');
const timer = setTimeout(() => {
clearTimeout(timer);
this.menuController.enable(false);
}, 100);
}
Another work-around is to show ion-menu when window.location.pathNameis not equal to /login with a *ngIf directive. It's working but i find this not very clean too...
Ionic Infos
Ionic:
ionic (Ionic CLI) : 4.1.1
Ionic Framework : #ionic/angular 4.0.0-beta.3
#angular-devkit/core : 0.7.4
#angular-devkit/schematics : 0.7.4
#angular/cli : 6.1.4
#ionic/ng-toolkit : 1.0.6
#ionic/schematics-angular : 1.0.5
This issue appears to be resolved in 4.0.0-beta.12 with the following:
ionViewDidEnter() {
this.menuController.enable(false);
}
ionViewDidLeave() {
this.menuController.enable(true);
}
The MenuController.enable() method is asynchronous.
You can create a Guest/Authenticated guard and enable it there, and then use it in pages using the canActivate route parameter in your pages. Then, when your page loads, the menu will be configured properly. For example, for authenticated guard:
#Injectable({
providedIn: 'root',
})
export class AuthenticatedGuard implements CanActivate {
constructor(private menuController: MenuController) {}
async canActivate(): Promise<boolean> {
const isAuthenticated = true; // Adjust where you get this value
await this.menuController.enable(isAuthenticated);
return isAuthenticated;
}
}
This will work for Ionic4/5.
You should use menuId property in your <ion-menu/> components for fine-tune identity and be able to use multiple menus. Then you can call .enable(isAuthenticated, menuId);

Handle a request with a specific function in a component

We are developing a component that handles OpenID Connect's implicit flow.
In step 5 of the flow, the "Authorization Server sends the End-User back to the Client with an ID Token and, if requested, an Access Token." We would like our component to handle that request, which will be to ~/openid-login.
How do we configure Aurelia to have it route to a function in our component?
export class OpenId {
// how do we route ~/openid-login to this?
public handleRequest() {
}
}
Note: Here is the work in progress.
Using a navStrategy within your routeConfig will allow you to do what ever you like before navigating to a page. See below:
import { autoinject } from 'aurelia-framework';
import { RouterConfiguration, Router, NavigationInstruction } from 'aurelia-router';
#autoinject
export class App {
router: Router;
configureRouter(config: RouterConfiguration, router: Router) {
let openIdNavStrat = (instruction: NavigationInstruction) => {
console.log('Do whatever we would like to do.');
// then redirect to where ever you would like.
instruction.config.moduleId = 'login';
}
config.map([
{ route: ['', 'login'], moduleId: 'login' },
{ route: 'openid-login', navigationStrategy: openIdNavStrat },
]);
this.router = router;
}
}
There is documentation on Navigation Strategies here: http://aurelia.io/hub.html#/doc/article/aurelia/router/latest/router-configuration/3

LoggedInOutlet angular2 authentication - Router v3.0.0-alpha8 - Where is ComponentInstruction?

I am using code like this to extend RouterOutlet and create app wide authentication and route protection
import {Directive, Attribute, ViewContainerRef, DynamicComponentLoader} from '#angular/core';
import {Router, ComponentInstruction} from '#angular/router';
import {Router} from '#angular/router';
import {RouterOutletMap} from '#angular/router/src/router_outlet_map';
import {RouterOutlet} from '#angular/router/src/directives/router_outlet';
import {Authentication} from '../common/authentication.service';
#Directive({
selector: 'router-outlet'
})
export class LoggedInRouterOutlet extends RouterOutlet {
publicRoutes:any;
isAuthenticated:boolean;
//private router: any;
constructor(public _elementRef: ElementRef, public _loader: DynamicComponentLoader,
public _parentRouter: Router, #Attribute('name') nameAttr: string, public authService:Authentication) {
super(_elementRef, _loader, _parentRouter, nameAttr);
this.isAuthenticated = authService.isLoggedIn();
//this.router = _parentRouter;
/**
* DEFINE PUBLIC ROUTES
*
* The Boolean following each route below denotes whether the route requires authentication to view.
*
* Format: key/value pair
* - key is the /route url "/login", "/signup", etc
* - value is a boolean true/false
* `true` means it's a publicly available route. No authentication required
* `false` means it's a protected route which is hidden until user is authenticated
*
*/
this.publicRoutes = {
'login': true,
'signup': true,
'404': true
};
} // end constructor
routeIsActive(routePath:string) {
return this.router.url == routePath;
}
activate(instruction: ComponentInstruction) {
// let url = instruction.urlPath;
let url = this.router.url;
// If the url doesn't match publicRoutes and they are not authenticated...
if (!this.publicRoutes[url] && !this.isAuthenticated) {
// todo: redirect to Login, may be there a better way?
this.router.navigateByUrl('/login');
}
return super.activate(instruction);
}
}
Problem is that ComponentInstruction does not exist in the new v3.0.0-alpha8 router, and the super method signature has changed. How do I update this to work in the new router? I cannot find any documentation explaining the changes.
ComponentInstruction has been deprecated. In the current RC4 version of Angular2, this class has been listed under reouter-deprecated. With RC5 coming in, this package would be dropped.
RouterOutlet has changed a lot over time and to make your class LoggedInRouterOultet work, you have to use CanActivate interface.
You can do something like this:
Have an injectable service like LoggedInActivator shown here:
import { Injectable } from '#angular/core';
import { Router, CanActivate } from '#angular/router';
import { LogInService } from './login.service';
#Injectable()
export class LoggedInActivator implements CanActivate {
constructor(private loginService: LogInService) {}
canActivate() {
return this.loginService.isLoggedIn();
}
}
Add canActivate and map it to LoggedInActivator on component while defining route:
{ path: 'home', component: HomeComponent, canActivate: [LoggedInActivator] }
I hope this helps!
because in new router, it uses CanActivate