ngFor not working, Firestore - google-cloud-firestore

I am attempting an example of using Angular5 with Firestore, but I cannot retrieve any data from my Firestore database. Any help would be greatly appreciated as this is a show stopper. The irony is I can insert new records into the database using the example, I just cannot retrieve anything. Thanks in advance.
app.component.html:
<ul *ngFor="let post of posts | async">
<li>
<strong>{{ post.title }}</strong>
<br>
{{ post.content }}
</li>
</ul>
app.component.ts:
import { Component } from '#angular/core';
import { AngularFirestore } from 'angularfire2/firestore';
import { AngularFirestoreCollection } from 'angularfire2/firestore';
import { AngularFirestoreDocument } from 'angularfire2/firestore';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
interface Post {
title: string;
content: string;
}
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
postsCollection: AngularFirestoreCollection<Post>;
posts: Observable<Post[]>;
constructor (private afs: AngularFirestore) {
}
ngOnit() {
this.postsCollection = this.afs.collection('posts');
this.posts = this.postsCollection.valueChanges();
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppComponent } from './app.component';
import { AngularFireModule } from 'angularfire2';
import { AngularFirestoreModule } from 'angularfire2/firestore';
import { FormsModule } from '#angular/forms';
var firebaseConfig = {
apiKey: "edited but correct",
authDomain: "edited but correct",
databaseURL: "edited but correct",
projectId: "edited but correct",
storageBucket: "",
messagingSenderId: "edited but correct"
};
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AngularFireModule.initializeApp(firebaseConfig),
AngularFirestoreModule,
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }

Looks like a typo:
ngOnit() {
Should be:
ngOnInit() {}
(You might even need ngAfterContentInit() if it's still not ready to load at that point in the lifecycle.)

The error is in this line
ngOnInit() {
this.postsCollection = this.afs.collection('posts'); <<HERE
this.posts = this.postsCollection.valueChanges();
}
Change it to:
this.postCollection = this.afs.collection< post > ('posts')
For reference you can read this page:
https://blog.angular.io/improved-querying-and-offline-data-with-angularfirestore-dab8e20a4a06

Related

Why do I get the NG0303 or NG0300 errors? (Angular Testing, Karma Jasmine)

I have several components (about,service,dashboard, etc) in which a header component is added. The application is running fine. However, I am getting errors when testing.
import { Component } from '#angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '#angular/core/testing';
import { IonicModule } from '#ionic/angular';
import { SettingsPage } from './settings.page';
describe('SettingsPage', () => {
let component: SettingsPage;
let fixture: ComponentFixture<SettingsPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ SettingsPage,MockHeaderComponent ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(SettingsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
#Component({
selector: 'app-header',
template: ''
})
class MockHeaderComponent {
}
First Error
Chrome 93.0.4577.82 (Windows 10): Executed 22 of 26 (1 FAILED) (0 secs / 5.88 secs)
ERROR: 'NG0303: Can't bind to 'headline' since it isn't a known property of 'app-header'.'
headline is a variable that I declared in my header component and use in my components to give me the correct title.
Of course, I already looked for solutions on the Internet and came across the following Stack Overflow post: Unit test Angular with Jasmine and Karma, Error:Can't bind to 'xxx' since it isn't a known property of 'xxxxxx'.
Therefore, I have imported and declared my HeaderComponent.
import { Component } from '#angular/core';
import { ComponentFixture, TestBed, waitForAsync } from '#angular/core/testing';
import { IonicModule } from '#ionic/angular';
import { HeaderComponent } from '../header/header.component';
import { SettingsPage } from './settings.page';
describe('SettingsPage', () => {
let component: SettingsPage;
let fixture: ComponentFixture<SettingsPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ SettingsPage,HeaderComponent,MockHeaderComponent ],
imports: [IonicModule.forRoot()]
}).compileComponents();
fixture = TestBed.createComponent(SettingsPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', () => {
expect(component).toBeTruthy();
});
});
#Component({
selector: 'app-header',
template: ''
})
class MockHeaderComponent {
}
Unfortunately, the following error occurred.
Chrome 93.0.4577.82 (Windows 10) SettingsPage should create FAILED
Failed: NG0300: Multiple components match node with tagname app-header. Find more at https://angular.io/errors/NG0300
error properties: Object({ code: '300' })
Error: NG0300: Multiple components match node with tagname app-header. Find more at https://angular.io/errors/NG0300
at throwMultipleComponentError (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:6779:1)
at findDirectiveDefMatches (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:10344:1)
at resolveDirectives (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:10158:1)
at elementStartFirstCreatePass (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:14772:1)
at ɵɵelementStart (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:14809:1)
at ɵɵelement (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:14888:1)
at SettingsPage_Template (ng:///SettingsPage.js:8:9)
at executeTemplate (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:9600:1)
at renderView (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:9404:1)
at renderComponent (node_modules/#angular/core/__ivy_ngcc__/fesm2015/core.js:10684:1)
Error: Expected undefined to be truthy.
at <Jasmine>
at UserContext.<anonymous> (src/app/components/settings/settings.page.spec.ts:24:23)
at ZoneDelegate.invoke (node_modules/zone.js/dist/zone-evergreen.js:364:1)
at ProxyZoneSpec.push.QpwO.ProxyZoneSpec.onInvoke (node_modules/zone.js/dist/zone-testing.js:292:1)
Chrome 93.0.4577.82 (Windows 10): Executed 26 of 26 (7 FAILED) (1.712 secs / 1.658 secs)
Can anyone tell me what I am doing wrong?
UPDATE 1:
My ComponentsModule class in which I integrate all reusable components:
import {NgModule} from '#angular/core';
import {HeaderComponent} from './header/header.component';
import { FooterComponent } from './footer/footer.component';
#NgModule({
declarations: [HeaderComponent, FooterComponent],
exports: [HeaderComponent, FooterComponent]
})
export class ComponentsModule{}
My html:
<ion-header>
<app-header [headline]="headlines.settings"></app-header>
</ion-header>
<ion-content>
</ion-content>
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { IonicModule } from '#ionic/angular';
import { SettingsPageRoutingModule } from './settings-routing.module';
import { SettingsPage } from './settings.page';
import { ComponentsModule } from '../components.module';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ComponentsModule,
SettingsPageRoutingModule
],
declarations: [SettingsPage]
})
export class SettingsPageModule {}
setting.page.ts
import { Component, OnInit } from '#angular/core';
import { lablesHeadlines } from 'src/environments/lables';
#Component({
selector: 'app-settings',
templateUrl: './settings.page.html',
styleUrls: ['./settings.page.scss'],
})
export class SettingsPage implements OnInit {
lablesHeadlines = lablesHeadlines;
headlines = lablesHeadlines;
constructor() { }
ngOnInit() {
}
}
setting.module.ts
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { FormsModule } from '#angular/forms';
import { IonicModule } from '#ionic/angular';
import { SettingsPageRoutingModule } from './settings-routing.module';
import { SettingsPage } from './settings.page';
import { ComponentsModule } from '../components.module';
#NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
ComponentsModule,
SettingsPageRoutingModule
],
declarations: [SettingsPage]
})
export class SettingsPageModule {}
Problem Solved. https://testing-angular.com/testing-components-with-children/#testing-components-with-children showed me the solution. That I write unit tests, I can do with
schemas: [NO_ERRORS_SCHEMA] to ignore the components in the top-level components. The low-level components are ready checked in their own tests.
I strongly advise to use the link above if you want to learn about testing in Angular.
Here is my Updated Sourcecode:
import { HttpClientTestingModule } from '#angular/common/http/testing';
import { ComponentFixture, TestBed, waitForAsync } from '#angular/core/testing';
import { IonicModule } from '#ionic/angular';
import { AboutClientServiceService } from 'src/app/services/about-client-service.service';
import { AppComponent } from 'src/app/app.component';
import { MockAboutClientService } from 'src/app/Mock/MockAboutClientService';
import { AboutPage } from './about.page';
import { Component } from '#angular/core';
import { NO_ERRORS_SCHEMA } from '#angular/core';
describe('AboutPage', () => {
let component: AboutPage;
let fixture: ComponentFixture<AboutPage>;
beforeEach(waitForAsync(() => {
TestBed.configureTestingModule({
declarations: [ AboutPage, MockHeaderComponent ],
schemas: [NO_ERRORS_SCHEMA],
imports: [IonicModule, HttpClientTestingModule],
providers: [AppComponent, AboutClientServiceService]
}).compileComponents();
TestBed.overrideComponent(
AboutPage,
{
set: {
providers: [
{ provide: AboutClientServiceService, useClass: MockAboutClientService }]
}
});
fixture = TestBed.createComponent(AboutPage);
component = fixture.componentInstance;
fixture.detectChanges();
}));
it('should create', (done) => {
expect(component).toBeTruthy();
expect(component.version).toBeDefined();
done();
});
});
#Component({
selector: 'app-header',
template: ''
})
class MockHeaderComponent {
}

Ionic 5 Google Recaptcha don't show - ng-recaptcha

I want to create a web app with a registration and the Google Recaptcha. I have oriented on this example:
I want to use the normal version use, but the Google Recaptcha will not display in the HTML. what do I wrong?
Here is my code, is something missing pls write to me.
app.module.ts:
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { SplashScreen } from '#ionic-native/splash-screen/ngx';
import { StatusBar } from '#ionic-native/status-bar/ngx';
import { AppComponent } from './app.component';
import { AppRoutingModule } from './app-routing.module';
import { RecaptchaModule, RECAPTCHA_SETTINGS, RecaptchaSettings } from 'ng-recaptcha';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [BrowserModule, IonicModule.forRoot(), AppRoutingModule, RecaptchaModule],
providers: [
StatusBar,
SplashScreen,
{
provide: RECAPTCHA_SETTINGS,
useValue: {
siteKey: '6Lee7qgZAAAAAC6i7J0fkf0_7ShBQKSXx8MafWHZ',
} as RecaptchaSettings,
},
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
],
bootstrap: [AppComponent]
})
export class AppModule {}
home.page.html
<ion-header [translucent]="true">
<ion-toolbar>
<ion-title>
Blank
</ion-title>
</ion-toolbar>
</ion-header>
<ion-content [fullscreen]="true">
<re-captcha (resolved)="resolveCaptcha($event)"></re-captcha>
</ion-content>
home.page.ts
import { Component } from '#angular/core';
import { RecaptchaModule } from 'ng-recaptcha'; // I don't if I need this import in this file
#Component({
selector: 'app-home',
templateUrl: 'home.page.html',
styleUrls: ['home.page.scss'],
})
export class HomePage {
constructor() {}
resolveCaptcha(event)
{
console.log(event)
}
}
Thanks for the help.
I have found an answer for my problem:
*.html
<re-captcha (resolved)="resolved($event)"></re-captcha>
*.page.ts
resolved(response: string) {
console.log(`Resolved captcha with response: ${response}`); if(response != null)
if(response != null && response != undefined) {
this.captchaPassed = !this.captchaPassed;
}
}
*.module.ts
import { RecaptchaComponent, RECAPTCHA_SETTINGS, RecaptchaSettings, RecaptchaModule } from 'ng-recaptcha' // muss hinzugefühgt werden /** nur wenn es auf einer seite sein soll */
#NgModule({
imports: [
CommonModule,
...
RecaptchaModule,
],
declarations: [RegisterPage],
providers: [
{
provide: RECAPTCHA_SETTINGS,
useValue: {
siteKey: '6Lee7qgZAAAAAC6i7J0fkf0_7ShBQKSXx8MafWHZ',
} as RecaptchaSettings,
},
],
})

Nativescript-angular2 Uncaught (in promise): Error: Cannot match any routes with multiple nested routing

I'm developing a mobile app with nativescript + Angular 8. Basically the app download a fat json object from the backend and then with multiple nested routing give the possibility to select a specific action.
The routing chain (each moduel is the child of the previous) is written below:
app-routing.module.ts -> main-routing.module.ts -> asset-routing.module.ts -> future-state.routing.module.ts
in the main.component.html is rendered a list of selectable assets generated dynamically from the json downloaded. When an asset is clicked a new list of selectable future-state generated dynamically from the json for the specific asset is shown. When a future-state is selected a list of selectable activities generated dynamically from the json for the specific future-state is shown. At the end the user can select the activity and the data is sent back to the backend.
In the selection phase everything is ok until the future-state item selection. When I try to select a future-state the code return me the Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: ....
future-state.commponent.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from "#angular/router";
import { RouterExtensions } from "nativescript-angular/router";
import { GlobalVariablesService } from '../../../_services/global-variables.service';
import { AndonPossibleIssueOpenStateDto } from '../../../_models/andon-possible-issue-open-state-dto';
#Component({
selector: 'ns-future-state',
templateUrl: './future-state.component.html',
styleUrls: ['./future-state.component.css']
})
export class FutureStateComponent implements OnInit {
id: number;
andonPossibleIssueOpenStateDto: AndonPossibleIssueOpenStateDto;
constructor(
private globalVariables: GlobalVariablesService,
private _route: ActivatedRoute,
private _routerExtensions: RouterExtensions
) { }
ngOnInit(): void {
const idFutureState = +this._route.snapshot.params.id;
this._route.params.subscribe(params => { this.id = params['id']; });
//this.andonPossibleIssueOpenStateDto=this.globalVariables.getAndonBotAssetPossibleStateIssueDto().find(function(element){return element.asset.id==idAsset}) as AndonPossibleIssueOpenStateDto;
}
onBackTap(): void {
this._routerExtensions.back();
}
}
future-state.module.ts
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { FutureStateRoutingModule } from "./future-state-routing.module";
import { FutureStateComponent } from "./future-state.component";
import { ActivityComponent } from "./activity/activity.component";
#NgModule({
imports: [
NativeScriptCommonModule,
FutureStateRoutingModule
],
declarations: [
FutureStateComponent,
ActivityComponent
],
exports: [FutureStateComponent],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class FutureStateModule { }
future-state-routing.module.ts
import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { FutureStateComponent } from "./future-state.component";
import { ActivityComponent } from "./activity/activity.component";
const routes: Routes = [
{
path: "",
component: FutureStateComponent
},
{
path: "activity/:id",
component: ActivityComponent
}
];
#NgModule({
imports: [NativeScriptRouterModule.forChild(routes)],
exports: [NativeScriptRouterModule]
})
export class FutureStateRoutingModule { }
asset.component.ts
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute } from "#angular/router";
import { RouterExtensions } from "nativescript-angular/router";
import { GlobalVariablesService } from '../../_services/global-variables.service';
import { AndonBotAssetPossibleStateIssueDto } from '../../_models/andon-bot-asset-possible-state-issue-dto';
#Component({
selector: 'ns-asset',
templateUrl: './asset.component.html',
styleUrls: ['./asset.component.css']
})
export class AssetComponent implements OnInit {
id: number;
andonBotAssetPossibleStateIssueDto: AndonBotAssetPossibleStateIssueDto;
constructor(
private globalVariables: GlobalVariablesService,
private _route: ActivatedRoute,
private _routerExtensions: RouterExtensions
) { }
ngOnInit(): void {
const idAsset = +this._route.snapshot.params.id;
this.id = this._route.snapshot.params['id'];
console.log(this._route.snapshot.children);
console.log(this._route.snapshot.routeConfig);
this.andonBotAssetPossibleStateIssueDto=this.globalVariables.getAndonBotAssetPossibleStateIssueDto().find(function(element){return element.asset.id==idAsset}) as AndonBotAssetPossibleStateIssueDto;
console.log(this.andonBotAssetPossibleStateIssueDto.asset);
console.log(this._route.firstChild);
}
onBackTap(): void {
this._routerExtensions.back();
}
}
asset.coponent.html
<ActionBar class="action-bar">
<Label class="action-bar-title" [text]="andonBotAssetPossibleStateIssueDto.asset.name"></Label>
</ActionBar>
<StackLayout class="page page-content">
<ListView [items]="andonBotAssetPossibleStateIssueDto.possibleStateIssueDto.optionStateIssue" class="list-group">
<ng-template let-item="item">
<Label [nsRouterLink]="['./futureState', item.futureState.id]" [text]="item.futureState.name" class="list-group-item"></Label>
</ng-template>
</ListView>
</StackLayout>
asset.module.ts
import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { AssetRoutingModule } from "./asset-routing.module";
import { AssetComponent } from "./asset.component";
import { FutureStateModule } from "./future-state/future-state.module";
#NgModule({
imports: [
NativeScriptCommonModule,
AssetRoutingModule,
FutureStateModule
],
declarations: [
AssetComponent
],
exports: [AssetComponent],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AssetModule { }
asset-routing.module.ts
import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { NSEmptyOutletComponent } from "nativescript-angular";
import { AssetComponent } from "./asset.component";
import { FutureStateComponent } from "./future-state/future-state.component";
const routes: Routes = [
{
path: "",
component: AssetComponent
},
{
path: "futureState/:id",
component: FutureStateComponent
},
{
path: "futureState",
component: NSEmptyOutletComponent,
loadChildren: () => import("~/app/main/asset/future-state/future-state.module").then((m) => m.FutureStateModule)
}
];
#NgModule({
imports: [NativeScriptRouterModule.forChild(routes)],
exports: [NativeScriptRouterModule]
})
export class AssetRoutingModule { }
Below the error message:
Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: 'main/asset/698/futureState/6'
JS: Error: Cannot match any routes. URL Segment: 'main/asset/698/futureState/6'
JS:
at ApplyRedirects.push.../node_modules/#angular/router/fesm5/router.js.ApplyRedirects.noMatchError (file:///node_modules#angular\router\fesm5\router.js:2459:0) [angular]
JS: at CatchSubscriber.selector (file:///node_modules#angular\router\fesm5\router.js:2440:0) [angular]
JS: at CatchSubscriber.push.../node_modules/rxjs/_esm5/internal/operators/catchError.js.CatchSubscriber.error (file:///node_modules\rxjs_esm5\internal\operators\catchError.js:34:0) [angular]
JS: at MapSubscriber.push.../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber._error (file:///node_modules\rxjs_esm5\internal\Subscriber.js:79:0) [angular]
JS: at MapSubscriber.push.../node_modules/rxjs/_esm5/internal/Subscriber.js.Subscriber.error (file:///data/data/org.nativescript.AndonMobile/fil...
The issue was that in the asset.component.html the link requested was /main/asset/[idAsset]/futureState/[idFutureState] instead the router dynamically generated in asset-routing.module.ts was something like /main/asset/futureState/[idFutureState].
I've modified the part:
{
path: "futureState/:id",
component: FutureStateComponent
}
with:
{
path: ":this.id/futureState/:id",
component: FutureStateComponent
}

two Listviews inside tabview don't work as expected

I have a code sharing Nativescript-Angular project. I am using two ListView's in a Lazy loaded module. The lazy loaded module is structured such that when I navigate to that module from AppModule.
<TabView id="tabViewContainer">
<page-router-outlet actionBarVisibility="never" *tabItem="{title: 'Players'}" name="playersTab"></page-router-outlet>
<page-router-outlet actionBarVisibility="never" *tabItem="{title: 'Event Requests'}" name="eventRequestsTab"></page-router-outlet>
</TabView>
Now each tab item is a page-router-outlet which routes to a child component and that child
component has ListView as parent element as shown below.
<ListView
class="list-group"
[items]="players"
(loaded)="onListViewLoaded($event)"
#listView
>
<ng-template let-player="item" let-third="third">
<GridLayout class="list-group-item" rows="*" columns="auto, *">
<Image
col="0"
[src]="player.photoURL"
class="thumb img-circle"
></Image>
<StackLayout col="1">
<Label
[text]="player.displayName"
class="list-group-item-heading"
></Label>
<Label
[text]="player.uid"
class="list-group-item-text"
textWrap="true"
></Label>
</StackLayout>
</GridLayout>
</ng-template>
</ListView>
Now the problem I am facing is when these two list views are shown side by side sometimes both the list views don't show anything and sometimes only the second tab shows data where as the first tab only shows the item dividers as shown below:-
Case 1 tab-1
Case 1 tab-2
Case 2 tab-1
Case 2 tab-2
The items always have more than one element but still this problem is being arised.
I have tried using the function listview.refresh() but still no success with that. I have also used ChangedDetectionStratergy.OnPush and called markedForRefresh function when data is received. I have tried using ObservableArray provided by Nativescript but I was bit confused while using that and also I felt it was not available for code sharing project.
I am frustrated since yesterday and it looks like a bug in Nativescript. Can you help overcome it so that both tabs shows the data always(knowing the arrays always have atleast one element) ?
Two listview is working inside tabView for example:-
app.component.html :-
`<TabView androidTabsPosition="bottom">
<page-router-outlet *tabItem="{title: 'Home', iconSource: getIconSource('home')}"
name="homeTab">
</page-router-outlet>
<page-router-outlet *tabItem="{title: 'Browse', iconSource: getIconSource('browse')}"
name="browseTab">
</page-router-outlet>
</TabView>`
app.component.ts:-
`import { Component, OnInit } from "#angular/core";
import { isAndroid } from "tns-core-modules/platform";
#Component({
selector: "ns-app",
moduleId: module.id,
templateUrl: "app.component.html"
})
export class AppComponent implements OnInit {
constructor() {
// Use the component constructor to inject providers.
}
ngOnInit(): void {
// Init your component properties here.
}
getIconSource(icon: string): string {
const iconPrefix = isAndroid ? "res://" : "res://tabIcons/";
return iconPrefix + icon;
}
}
`
app.module.ts :-
`import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptModule } from "nativescript-angular/nativescript.module";
import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
#NgModule({
bootstrap: [
AppComponent
],
imports: [
NativeScriptModule,
AppRoutingModule
],
declarations: [
AppComponent
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class AppModule { }
`
app.routing.ts :-
`import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NSEmptyOutletComponent } from "nativescript-angular";
import { NativeScriptRouterModule } from "nativescript-angular/router";
const routes: Routes = [
{
path: "",
redirectTo: "/(homeTab:home/default//browseTab:browse/default)",
pathMatch: "full"
},
{
path: "home",
component: NSEmptyOutletComponent,
loadChildren: "~/app/home/home.module#HomeModule",
outlet: "homeTab"
},
{
path: "browse",
component: NSEmptyOutletComponent,
loadChildren: "~/app/browse/browse.module#BrowseModule",
outlet: "browseTab"
}
];
#NgModule({
imports: [NativeScriptRouterModule.forRoot(routes)],
exports: [NativeScriptRouterModule]
})
export class AppRoutingModule { }
`
home.component.html :-
`<GridLayout class="page page-content">
<ListView [items]="items" class="list-group">
<ng-template let-item="item">
<ScrollView height="150">
<Label [text]="item.name" class="list-group-item"></Label>
</ScrollView>
</ng-template>
</ListView>
</GridLayout>`
home.component.ts:-
`import { Component, OnInit } from "#angular/core";
import { DataService, IDataItem } from "../shared/data.service";
#Component({
selector: "Home",
moduleId: module.id,
templateUrl: "./home.component.html"
})
export class HomeComponent implements OnInit {
items: Array<IDataItem>;
constructor(private _itemService: DataService) { }
ngOnInit(): void {
this.items = this._itemService.getItems();
}
}`
home.module.ts:-
`import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { HomeRoutingModule } from "./home-routing.module";
import { HomeComponent } from "./home.component";
import { ItemDetailComponent } from "./item-detail/item-detail.component";
#NgModule({
imports: [
NativeScriptCommonModule,
HomeRoutingModule
],
declarations: [
HomeComponent,
ItemDetailComponent
],
schemas: [
NO_ERRORS_SCHEMA
]
})
export class HomeModule { }`
home-routing.module.ts:-
`import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { HomeComponent } from "./home.component";
import { ItemDetailComponent } from "./item-detail/item-detail.component";
const routes: Routes = [
{ path: "default", component: HomeComponent },
{ path: "item/:id", component: ItemDetailComponent }
];
#NgModule({
imports: [NativeScriptRouterModule.forChild(routes)],
exports: [NativeScriptRouterModule]
})
export class HomeRoutingModule { }`
browse.component.html :-
`<GridLayout class="page page-content">
<ListView [items]="items" class="list-group">
<ng-template let-item="item">
<ScrollView height="150">
<Label [text]="item.name" class="list-group-item"></Label>
</ScrollView>
</ng-template>
</ListView>
</GridLayout>`
browse.component.ts:-
`import { Component, OnInit } from "#angular/core";
import { DataService, IDataItem } from "../shared/data.service";
#Component({
selector: "Browse",
moduleId: module.id,
templateUrl: "./browse.component.html"
})
export class BrowseComponent implements OnInit {
items: Array<IDataItem>;
constructor(private _itemService: DataService) { }
ngOnInit(): void {
this.items = this._itemService.getItems();
}
}
`
browse.module.ts:-
`import { NgModule, NO_ERRORS_SCHEMA } from "#angular/core";
import { NativeScriptCommonModule } from "nativescript-angular/common";
import { BrowseRoutingModule } from "./browse-routing.module";
import { BrowseComponent } from "./browse.component";
import { DataService } from "../shared/data.service";
#NgModule({
imports: [
NativeScriptCommonModule,
BrowseRoutingModule
],
declarations: [
BrowseComponent
],
schemas: [
NO_ERRORS_SCHEMA
],
providers:[
DataService
]
})
export class BrowseModule { }`
browse-routing.module.ts:-
`import { NgModule } from "#angular/core";
import { Routes } from "#angular/router";
import { NativeScriptRouterModule } from "nativescript-angular/router";
import { BrowseComponent } from "./browse.component";
const routes: Routes = [
{ path: "default", component: BrowseComponent }
];
#NgModule({
imports: [NativeScriptRouterModule.forChild(routes)],
exports: [NativeScriptRouterModule]
})
export class BrowseRoutingModule { }
`
Example Available On Here:-
Nativescript playground url

how to use angular/forms in angular 5?

I'm using angular 5 and now I need a form for user's sign-in. but when I run my project I got the error Can't bind to 'formGroup' since it isn't a known property of 'form'! here are some of my codes:
app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { FormsModule} from '#angular/forms';
import { appRoutes } from './app.routing.module'
import { AppComponent } from './app.component';
import { UserComponent } from './components/user/user.component';
#NgModule({
declarations: [
AppComponent,
UserComponent,
],
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes),
FormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
user.component.ts:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, Validators, FormControl } from '#angular/forms';
#Component({
selector: 'app-user',
templateUrl: './user.component.html',
styleUrls: ['./user.component.css']
})
export class UserComponent implements OnInit {
private form : FormGroup;
constructor(
private fb: FormBuilder
) { }
ngOnInit() {
this.form = this.fb.group({
username: [null, Validators.compose([Validators.required])],
password: [null, Validators.compose([Validators.required])]
})
}
show() {
const user = {
username: this.form.get('username').value,
password: this.form.get('password').value,
}
}
}
and this is my component.html:
<form [formGroup]="form" (ngSubmit)="show()">
<div>
<p>Sign in with your email to continue</p>
</div>
<div>
<div>
<input placeholder="Username" [formControl]="form.controls['username']">
</div>
<div>
<input type="password" placeholder="Password" [formControl]="form.controls['password']">
</div>
<button color="primary" type="submit">Login</button>
</div>
</form>
i did it in angular 4 and it worked well but now i get the errors bellow!
Can't bind to 'formControl' since it isn't a known property of 'input & Can't bind to 'formGroup' since it isn't a known property of 'form'!!!
what's wrong with the codes?
Try importing ReactiveFormsModule:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { appRoutes } from './app.routing.module'
import { AppComponent } from './app.component';
import { UserComponent } from './components/user/user.component';
#NgModule({
declarations: [
AppComponent,
UserComponent,
],
imports: [
BrowserModule,
RouterModule.forRoot(appRoutes),
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }