*ng-if not working inside ion-modal in ionic 5 - javascript

i am building a mobile app with ionic 5, when I try to call ion-modal that has an *ng-If in it, i would get this error
Can't bind to 'ngIf' since it isn't a known property of 'ion-header'.
The modal is a comment section in comment.page.ts, here is the code for the comment.page.html
<ion-header class="ion-no-border" *ngIf="!isLoading">
<ion-toolbar>
<ion-title class="centerAM">{{no_comm | shortNumber}} comment{{no_comm>1?'s':''}}</ion-title>
</ion-toolbar>
</ion-header>
<ion-content>
....
here is the code for the comment.module.ts
import { NgModule } from '#angular/core';
import { IonicModule } from '#ionic/angular';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { NgxEmojModule } from 'ngx-emoj';
import { CommentPageRoutingModule } from './comment-routing.module';
import { CommentPage } from './comment.page';
import { PipesModule } from '../../pipes/pipes.module';
#NgModule({
imports: [
CommonModule,
NgxEmojModule,
PipesModule,
FormsModule,
IonicModule,
CommentPageRoutingModule
],
schemas: [],
declarations: [ CommentPage]
})
export class CommentPageModule {}
here is the function that calls the modal from the home.page.ts
async CommentModal(i, id) {
const modal = await this.modalCtrl.create({
component: CommentPage,
componentProps:{id},
swipeToClose: true,
cssClass: 'comment-modal'
});
await modal.present();
return
}
If i should add the comment.module.ts in the home.module.ts or the app.module.ts, when the page loads, it will automatically load the modal without the user clicking anything, and i also removed the page from the route and it didn't work, please what am i doing wrong

It is likely that your modules are being lazy-loaded. In that case the docs suggest that you should import your modal module (CommentPageModule) inside of the module, where you require this modal.
In other words, you need:
...
#NgModule({
imports: [
...
CommentPageModule, // <--- here
]
...
export class YourMainModule {}
Otherwise, the modal component doesn't get fully loaded.
Quote from the docs:
When lazy loading a modal, it's important to note that the modal will not be loaded when it is opened, but rather when the module that imports the modal's module is loaded.

I got the same issue on angular 10, Ionic 5, and the issue resolved by just import
modal page in app.modual.ts like
import { ModalPage } from './modules/core/modal/modal/modal.page';
#NgModule({
declarations: [
...
ModalPage
]

just add the component which will be used
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
UpdatePageRoutingModule],
declarations: [UpdatePage, DownloadModalComponent],
entryComponents: [DownloadModalComponent]
})
export class UpdatePageModule {}
in modal in your module declarations and entryComponents like this
where DownloadModalComponent is a component which is being used in a modal of UpdatePage.

You need to make sure that you've imported the BrowserModule to your module.
import {BrowserModule} from '#angular/platform-browser';
....
#NgModule({
imports: [
BrowserModule,
]
....

Related

The selector " did not match any elements

I’m using Angular 8 with ASP.NET Core 2.2.
I have two pages Index.cshtml and Job newlist.cshtml
In page index.cshtml I use tag <app-job-newlist></app-job-newlist>.
Then in page newlist.cshtml I use tag <app-jobpicload></app-jobpicload>
When loading page newlist.cshtml, I see error:
ERROR Error: "The selector "app-job-newlist" did not match any elements"
this my code app-modules.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppRoutingModule } from './app-routing.module';
//import { CommnetComponent } from './commnet/commnet.component';
import { CommentComponent } from './comment/comment.component';
import { JobListComponent } from './job-list/job-list.component';
import { JobServiceService } from './services/job-service.service';
import { JobLoadFileComponent } from './job-load-file/job-load-file.component';
#NgModule({
declarations: [
CommentComponent,
JobListComponent,
JobLoadFileComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule
],
providers: [JobServiceService],
bootstrap: [ JobListComponent]
})
export class AppModule { }
Explain:
Every component you want to use in your angular app have to explicit
import in correct module or else you will see that error because
angular cant find selector tag for that component
Fix
Make sure to import your app-job-newlist to your module

Angular6 json schema form loads Bootstrap module

I'm using angular6-json-schema-form in Angular v6 project. I installed it with command:
$ yarn add angular6-json-schema-form
I imported Bootstrap4FrameworkModule like this:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { Bootstrap4FrameworkModule } from 'angular6-json-schema-form';
import { AppComponent } from './app.component';
#NgModule({
declarations: [ AppComponent ],
imports: [
BrowserModule
Bootstrap4FrameworkModule
],
providers: [],
bootstrap: [ AppComponent ]
})
export class AppModule { }
And my component is like the following:
<json-schema-form
loadExternalAssets="true"
[schema]="schema"
(onSubmit)="submit($event)">
</json-schema-form>
The generated forms works fine but the Bootstrap4 styling doesn't work. I have no styling only plain html.
Never mind I found the solution in Documentation. I need to specify the template/framwork in the component HTML:
<json-schema-form
loadExternalAssets="true"
[schema]="schema"
framework="bootstrap-4"
(onSubmit)="submit($event)">
</json-schema-form>

How to properly configure this dummy Angular project

I have this very basic project:
https://stackblitz.com/edit/angular-rktmgc-ktjk3n?file=index.html
This is the code on: /index.html
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
<div class="mat-app-background basic-container">
<br />
API reference for Angular Material slide-toggle<br /><br />
<select-reset-example>loading</select-reset-example>
<div style="margin-top:30px;">
<div style="color:#f00;margin-bottom:20px;">
Below is what I need to get it work like above (but it doesn't):
</div>
<mat-slide-toggle>Slide me!</mat-slide-toggle>
</div>
</div>
This is the code on: /app/select-reset-example.html
<mat-slide-toggle>Slide me!</mat-slide-toggle>
When loading the component: mat-slide-toggle through: select-reset-example it works, but when loading it directly on the index.html it doesn't.
My question is, how to configure the following /main.ts file in order to render the mat-slide-toggle directly on the index.html?
In case the scope be a problem, maybe is it possible to create a custom component which inherits from that mat-slide-toggle or MatSlideToggleModule class?
If possible, could you fork the project on stackblitz.com and give me the link
with a proper configuration?
import './polyfills';
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { BrowserModule } from '#angular/platform-browser';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { NgModule } from '#angular/core';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { MatSlideToggleModule } from '#angular/material';
import { SelectResetExample } from './app/select-reset-example';
import { HttpModule } from '#angular/http';
import { CdkTableModule } from '#angular/cdk/table';
#NgModule({
exports: [
MatSlideToggleModule,
]
})
export class DemoMaterialModule { }
#NgModule({
imports: [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
HttpModule,
DemoMaterialModule,
ReactiveFormsModule,
],
entryComponents: [SelectResetExample],
declarations: [SelectResetExample],
bootstrap: [SelectResetExample],
providers: []
})
export class AppModule { }
platformBrowserDynamic().bootstrapModule(AppModule);
This is the structure of the project:
Thanks!
Indeed there are several options which could be applied here.
Attempt 1
At first glance we can easily solve your problem by simply importing MatSlideToggle component and adding it to the bootstrap array:
import { MatSlideToggle } from '#angular/material';
#NgModule({
...
bootstrap: [SelectResetExample, MatSlideToggle ]
^^^^^^^^^^^^^^
cool, it was very easy!!!
})
export class AppModule { }
https://stackblitz.com/edit/angular-rktmgc-7h51hh?file=main.ts
Hmm, seems we've broken everything:).
Why?
Angular bootstraps SelectResetExample component. During this process it creates mat-slide-toggle that is part of select-reset-example.html template.
So now our html has two mat-slide-toggle tags.
And then angular bootstraps second component (MatSlideToggle) that will be applied to the first mat-slide-toggle. This way we can see that the first working slider lost text Slide me!.
Attempt 2
Let's change order of our bootstrapping components:
#NgModule({
...
bootstrap: [ MatSlideToggle, SelectResetExample ]
})
export class AppModule { }
https://stackblitz.com/edit/angular-rktmgc-mkm7ry?file=main.ts
The second slider works now but wait... We again lost the text.
The main reason of this is that angular can't process projectable nodes on bootstrapping component.
Attempt 3
Angular gives the opportunity to override bootstrapping process by writing code within ngDoBootstrap method of #NgModule. Let's try...
import { ApplicationRef, ComponentFactoryResolver, Injector, NgModuleRef } from '#angular/core';
#NgModule({
// we replaced bootstrap option with entryComponents
entryComponents: [SelectResetExample, MatSlideToggle],
})
export class AppModule {
constructor(
private resolver: ComponentFactoryResolver,
private ngModule: NgModuleRef<any>) {}
ngDoBootstrap(appRef: ApplicationRef) {
const factory = this.resolver.resolveComponentFactory(MatSlideToggle);
const target = document.querySelector('mat-slide-toggle');
const compRef = factory.create(
Injector.NULL,
[Array.from(target.childNodes)], // passing projectable nodes
target,
this.ngModule);
appRef.attachView(compRef.hostView);
appRef.bootstrap(SelectResetExample);
}
}
https://stackblitz.com/edit/angular-rktmgc-ncyebq?file=index.html
Here i am bootstrapping our components throught custom method ngDoBootstrap. And it works but...
What is this? Do I really need to know this?
I don't think so. There must be some other way out.
Attempt 4
in order not to complicate our live we should follow the design of angular framework. For that it would be better to have one root component. Let's create it:
app.component.ts
#Component({
selector: '.mat-app-background.basic-container',
templateUrl: './app.component.html',
})
export class AppComponent {
}
app.component.html
<br />
API reference for Angular Material slide-toggle<br /><br />
<select-reset-example>loading</select-reset-example>
<div style="margin-top:30px;">
<div style="color:#f00;margin-bottom:20px;">
Below is what I need to get it work like above (but it doesn't):
</div>
<mat-slide-toggle>Slide me!</mat-slide-toggle>
</div>
module
declarations: [SelectResetExample, AppComponent],
bootstrap: [AppComponent],
index.html
<div class="mat-app-background basic-container"></div>
i moved styles to external resouces
Stackblitz Example

Creating a Master/Detail app in Plunker with Ionic 2

Building on from some good standard Ionic 2 plunkers here http://plnkr.co/edit/ZsoPeE?p=preview and
http://plnkr.co/edit/WBeRRJyYucLwvckjh5W7?p=preview
Can you help tweak my Master/Detail Plunker? I thought I had all the parts in place but missing something as it produces a white screen.
Here is my attempt at a Master/Detail plunk
http://plnkr.co/edit/7NHIYMA3TUdd5nOkoXyF?p=preview
import { NgModule } from '#angular/core';
import { IonicApp, IonicModule } from 'ionic-angular';
import { AppComponent } from './app.component';
import { HomePage } from '../pages/home/home';
import { MasterPage } from '../pages/master/master';
import { DetailPage } from '../pages/detail/detail';
import { Sheetsu } from '../providers/sheetsu';
#NgModule({
imports: [ IonicModule.forRoot(AppComponent) ],
declarations: [ AppComponent, HomePage, MasterPage, DetailPage],
entryComponents: [ HomePage, MasterPage, DetailPage ],
bootstrap: [ IonicApp ],
providers: [ Sheetsu ]
})
export class AppModule { }
Fixed Plunker: http://plnkr.co/edit/5V36C9QHYDGBIqSIfBUl?p=preview
You had several mistakes
1) import { Sheetsu } from '../providers/sheetsu'; <- your file is called Sheetsu, with a capital S
2) Your relative paths are wrong, you've made it complicated for yourself by putting pages: 'pages', inside your config, and for example:
import { MasterPage } from '../pages/master/master';
inside HomePage should be
import { MasterPage } from '../master/master';
3) You are using "module": "commonjs", but not taking advantage of relative html urls:
templateUrl: 'pages/master/master.html', -> `templateUrl: './master.html',`
with moduleId: module.id inside your #Component
4) Your button click return this.http.get('../assets/sheetsu.json') should be return this.http.get('./assets/sheetsu.json')

Angular2 unable to import FormsModule with javascript

I am doing the Angular2 Heroes Tutorial:
https://angular.io/docs/ts/latest/tutorial/toh-pt1.html
in plain Javascript (not Typescript) and i am having trouble to Import the Forms Module as mentioned: (description is only for Typescript):
Before we can use two-way data binding for form inputs, we need to import the FormsModule package in our Angular module. We add it to the NgModule decorator's imports array. This array contains the list of external modules used by our application.
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
#NgModule({
imports: [
BrowserModule,
FormsModule
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
When i am adding the Forms module to my app.module.js import array, it fails to find the module:
zone.js:129 Uncaught Error: Unexpected value 'undefined' imported by the module 'class2'
Here is my app.module.js:
(function(app) {
app.AppModule =
ng.core.NgModule({
imports: [ ng.platformBrowser.BrowserModule, ng.common.FORM_DIRECTIVES],
declarations: [ app.AppComponent],
bootstrap: [ app.AppComponent ]
})
.Class({
constructor: function() {}
});
})(window.app || (window.app = {}));
in my node_modules folder the Forms module exists. If i remove "ng.common.FORM_DIRECTIVES" from the imports array, no error is thrown.
The Content of console.dir(ng) is:
Object
common:Object
compiler:Object
core:Object
coreTokens:Object
platformBrowser:Object
platformBrowserDynamic:Object
probe
:
inspectNativeElement(element /** TODO #9100 */)
__proto__:Object
The content of console.dir(ng.forms) is:
undefined
I am sorry, i found the error. As so often it was nothing having to do with typescript or angular, i just had to add the script tag in the index.html file to load the forms.umd.js:
<script src="../node_modules/#angular/forms/bundles/forms.umd.js"></script>
now i can import the Forms Module with the following code and i can use the ngModule functionality:
ng.core.NgModule({
imports: [ ng.platformBrowser.BrowserModule, ng.forms.FormsModule],
declarations: [ app.AppComponent],
bootstrap: [ app.AppComponent ]
})
Try using import { FORM_DIRECTIVES } from 'angular2/common';
Source: Angular 2 two way binding using ngModel is not working
EDIT:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FORM_DIRECTIVES } from 'angular2/common';
import { AppComponent } from './app.component';
#NgModule({
imports: [
BrowserModule,
FORM_DIRECTIVES
],
declarations: [
AppComponent
],
bootstrap: [ AppComponent ]
})
export class AppModule { }
If this doesn't work, post the console.dir(ng); again( with this code in use ).

Categories