Ionic3 lazy loading a Component in Page - lazy-loading

I am working to an app that will be like a ppt presentation with a homepage, then slides(which are lazyloaded), each slide will have a navigation bar with: prev, home and next btn.
SO I thought: if that navigation will be common for all slides why not have it like a separate component, with a navCtrl and nextSLide will be transmitted like an #Input(), goHome- will be a seRoot() and back will be navCtrl.pop() - navPop directly in html. I will post code below :
slide1.ts
#IonicPage()
#Component({
selector: 'page-slide1',
templateUrl: 'slide1.html',
})
export class Slide1Page {
link:string = "Slide2Page"
}
slide1.htm
<ion-content padding>
<app-nav [toSlide]="link"></app-nav>
</ion-content>
nav.ts
#IonicPage()
#Component({
selector: 'app-nav',
templateUrl: 'nav.html'
})
export class NavComponent {
#Input() toSlide;
constructor(public navCtrl: NavController) {}
}
nav.html
<button class="nav_left" navPop></button>
<button class="to_home" (click)="goHome()"></button>
<button class="nav_right" [navPush]="toSlide"></button>
nav.module.ts I've made it IonicPagemodule
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { NavComponent } from './nav';
#NgModule({
declarations: [
NavComponent,
],
imports: [
IonicPageModule.forChild(NavComponent),
],
exports: [
NavComponent
]
})
export class NavComponentModule {}
When I navigate from homePage to slide1Page I got a long error(chunk of it here):
Uncaught (in promise): Error: Template parse errors: Can't bind to 'toSlide' since it isn't a known property of 'app-nav'. 1. If 'app-nav' is an Angular component and it has 'toSlide' input, then verify that it is part of this module. 2. If 'app-nav' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
I want to know if my approach is good or doable, cuz I don't wanna spend time for nothing. Thanks!

Ok, so there error was because I didn't include NavCOmponent in slide1.module.ts
import { NavComponent } from './../../components/nav/nav';
import { NgModule } from '#angular/core';
import { IonicPageModule } from 'ionic-angular';
import { Slide1Page } from './slide1';
#NgModule({
declarations: [
Slide1Page,
NavComponent
],
imports: [
IonicPageModule.forChild(Slide1Page),
],
exports: [
Slide1Page,
NavComponent
]
})
export class Slide1PageModule {}
Still - is this a good approach?

Related

How to use ngModel on input (Angular - TypeScript)

I'm pretty new to Angular, and I'm trying to make a form to ask for some user's input so I can make a simple signup. When I try to use ngModel in my input for two way data binding, I'm getting an error saying "Can't bind to 'ngModel' since it isn't a known property of 'input'". After searching the forums for a while, I've seen the common solution is to import FormsModule in my app.module, so I did it, and nothing changed. The strange part is that after importing it, typescript stopped showing the error on the editor, but when I try to do "ng serve" it throws it in the console.
I'll add my relevant code here so you can check it, but after almost an hout trying to find the solution I keep getting the error so that's why I came and asked, because I can't seem to find a proper solution on other related questions.
I'm using primeNg also if that's any relevant.
(Note that I only have one input field in my form because I wanted to resolve the issue first before adding more inputs)
sign-up.component.html
<div class="text-layout">
<div class="p-fluid p-grid">
<div class="p-field p-col-12 p-md-4">
<span class="p-float-label">
<input pInputText [(ngModel)]="usernamevalue" type="text" id="username">
</span>
</div>
</div>
</div>
sign-up.component.ts
import { Component, OnInit } from '#angular/core';
#Component({
selector: 'app-sign-up',
templateUrl: './sign-up.component.html',
styles: [
]
})
export class SignUpComponent implements OnInit {
usernamevalue: any;
constructor() { }
ngOnInit(): void {
}
}
sign-up.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { SignUpComponent } from './sign-up.component';
import { PrimeNgModule } from '../prime-ng/prime-ng.module';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
declarations: [
SignUpComponent
],
imports: [
CommonModule,
PrimeNgModule,
FormsModule,
ReactiveFormsModule
],
exports: [
SignUpComponent
]
})
export class SignUpModule { }
app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppComponent } from './app.component';
import { MainPageModule } from './main-page/main-page.module';
import { SharedModule } from './shared/shared.module';
import { AppRouterModule } from './app-router.module';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
MainPageModule,
SharedModule,
AppRouterModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
If you need me to provide any more code I'll be willing to help and post it under these, thank you very much for your time!
The problem is that [(ngModel)] requires a name tag.
You can solve this by:
<div class="text-layout">
<div class="p-fluid p-grid">
<div class="p-field p-col-12 p-md-4">
<span class="p-float-label">
<input pInputText [(ngModel)]="usernamevalue" type="text" name="usernamevalue">
</span>
</div>
</div>
</div>
This is stupid, yes, but required in angular.😌
Happy Coding!!

Ionic PDFJS Cannot match any routes. URL Segment: 'lib/ui/index.html'

I am trying to open a pdf in my ionic 5 application with the plugin
npm i # pdftron / pdfjs-express --save
but ionic shows me the error Cannot match any routes. URL Segment: 'lib / ui / index.html'
please how to correct this error?
my code:
app.component.html
<div class="page">
<div class="header">Angular sample</div>
<div #viewer class="viewer"></div>
</div>
app.component.ts
import { Component, ViewChild, OnInit, ElementRef, AfterViewInit } from '#angular/core';
import WebViewer from '#pdftron/pdfjs-express';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, AfterViewInit {
#ViewChild('viewer', { static: false }) viewer: ElementRef;
wvInstance: any;
ngAfterViewInit(): void {
WebViewer({
path: '../lib',
initialDoc: '../files/webviewer-demo-annotated.pdf'
}, this.viewer.nativeElement).then(instance => {
this.wvInstance = instance;
})
}
ngOnInit() {
}
}
Have you used any of our angular samples here https://github.com/PDFTron?q=angular? You can clone one of the samples and take a look at how it is implemented

TypeError: this.navigator.element.pushPage is not a function

Im using onsen-ui with angular 8 I'm getting error in the below function, I am not sure why this happens, because it is the code from the onsenUI-page.
push(event, value){
console.log(value);
this.navigator.element.pushPage(value, {animation: 'slide'});
}
My code
Sidemenu.html
<ons-page id="menu">
<ons-toolbar>
<div class="center">Menu</div>
</ons-toolbar>
<div class="background"></div>
<div class="content">
<ons-list>
<ons-list-item (click)="push($event, 'HomeComponent')" tappable>
Home
</ons-list-item>
<ons-list-item (click)="push($event, 'FormComponent')" tappable>
Form
</ons-list-item>
</ons-list>
</div>
</ons-page>
sidemenucomponent.html
import { Component, OnInit } from '#angular/core';
import { ViewChild, OnsNavigator} from 'ngx-onsenui';
import { HomeComponent } from './../home/home.component';
#Component({
selector: 'ons-page[third]',
templateUrl: './sidemenu.component.html',
styleUrls: ['./sidemenu.component.scss'],
providers:[OnsNavigator]
})
export class SidemenuComponent implements OnInit {
constructor(private navigator: OnsNavigator) { }
ngOnInit() {
}
push(event, value){
console.log(value);
this.navigator.element.pushPage(value, {animation: 'slide'});
}
}
Im getting error
ERROR TypeError: this.navigator.element.pushPage is not a function
at SidemenuComponent.push (sidemenu.component.ts:20)
at Object.eval [as handleEvent] (VM5587 SidemenuComponent.ngfactory.js:21)
at handleEvent (core.js:43993)
at callWithDebugContext (core.js:45632)
at Object.debugHandleEvent [as handleEvent] (core.js:45247)
at dispatchEvent (core.js:29804)
at core.js:42925
at HTMLElement.<anonymous> (platform-browser.js:2668)
at ZoneDelegate.invokeTask (zone-evergreen.js:391)
at Object.onInvokeTask (core.js:39680)
Below is the app component i added but still getting same error
app.component.html
<ons-navigator swipeable [page]="sidePage"></ons-navigator>
<ons-page id="apppage">
<ons-splitter #splitter>
<ons-splitter-side [page]="sidePage" side="left" width="300px" collapse swipeable>
</ons-splitter-side>
<ons-splitter-content [page]="contentPage">
</ons-splitter-content>
</ons-splitter>
</ons-page>
<router-outlet></router-outlet>
app.component.ts
import { Component } from '#angular/core';
import { HomeComponent } from './components/home/home.component';
import { SidemenuComponent } from './components/sidemenu/sidemenu.component';
import { MenuService } from './menu-service.service';
import {
Injectable,
ViewChild,
} from 'ngx-onsenui';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'my-app';
sidePage = SidemenuComponent;
contentPage = HomeComponent;
#ViewChild('splitter',{static: false}) splitter;
constructor(private menuService: MenuService) {
this.menuService.menu$.subscribe(() => this.splitter.nativeElement.side.open());
}
}
Please can anyone help.

Angular template rendering non-encoded URL

How do I render a URL which is not encoded. Below is a sample
import { Component } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'demo-app',
template: `<a [routerLink]="stringURL">Click here</a>`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
stringURL:string;
constructor(){
this.stringURL = "/url;mode=3"
}
}
The URL in the template has encoded string like /url%3Bmode%3D3 and I want it like /url;mode=3
How can I achieve this.
Here's the sample : https://stackblitz.com/edit/angular-q6mf3p
Thanks
You have to disable angular default URL encoding.
This post explains the solution quite well.
If the link is static, you can use the directive as follows: link to user component
If you use dynamic values to generate the link, you can pass an array of path segments, followed by the params for each segment.
For instance ['/url',{mode: 3}] means that we want to generate a link to /url;mode=3.
you code will work see this new link click to see
import { Component } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'demo-app',
template: `<a [routerLink]="stringURL">Click here</a>`,
styleUrls: [ './app.component.css' ]
})
export class AppComponent {
stringURL:any;
constructor(){
this.stringURL = ["/url",{mode:3}]
}
}

Accessing angular 2 directive attached to component selector

I could use some help.
Lets say i have a directive:
import { Directive } from '#angular/core';
#Directive( {
selector: '[appMyDirective]'
} )
export class MyDirective {
constructor () {
}
seyHey () {
console.log( 'hey hey!' );
}
}
And i have a component
import { Component, OnInit, ViewChild } from '#angular/core';
import { MyDirective } from "../my-directive.directive";
#Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit {
#ViewChild(MyDirective) appMyDirective: MyDirective;
constructor() { }
ngOnInit() {
this.appMyDirective.seyHey();
}
}
Component template:
<p appMyDirective>
my-component works!
</p>
app.component.html
<app-my-component></app-my-component>
All good. I get hey hey on console. But i want to attach directive to component selector like so:
<app-my-component appMyDirective></app-my-component>
And be able to call directive methods inside component class. How?
Tnx for your time
Try accessing it like you would a Provider (in the constructor).
In your example...
import { Component, OnInit, Optional } from '#angular/core';
import { MyDirective } from "../my-directive.directive";
#Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponentComponent implements OnInit {
constructor(#Optional() private appMyDirective: MyDirective) { }
ngOnInit() {
this.appMyDirective.seyHey();
}
}
I've added the #Optional in case the directive is optional on your component, which may occur in some cases.
Oh, and this also works on Directive to Directive..
#Directive({....})
export class MyDirective {
constructor(#Optional() private appMyDirective: MyDirective) { }
}
This was tested on my project and works. The property was even ready in the constructor. Just keep an eye on any cyclical references (e.g. component calls the directive, the directive calls the component, etc..)
Happy Coding.