Whereto with `disableDeprecatedForms(),provideForms()` in RC5? - forms

Without deactivating the old forms with (in RC4 > it was a part of bootstrapping process)
disableDeprecatedForms(),
provideForms()
I cannot render data (got over observables) e.g. in a select boxes (options/*ngFor).
Where can I deactivate the old forms in RC5?
(OverviewComponent below has the form with select boxes)
That's the new main.ts:
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
That's the new app.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { APP_BASE_HREF } from '#angular/common';
import { RouterModule } from '#angular/router';
import { HttpModule } from '#angular/http';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { routes } from './app.routes';
import {
OverviewComponent,
} from './forms/index';
#NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule,
RouterModule.forRoot(routes),
],
declarations: [
AppComponent,
OverviewComponent,
BasisdateneingabeComponent
],
providers: [{
provide: APP_BASE_HREF,
useValue: '<%= APP_BASE %>'
}],
bootstrap: [AppComponent]
})
export class AppModule { }

According to this, disableDeprecatedForms() still exists in RC5 but has been deprecated. Your problems are probably coming from the fact that your application is using the RC4 forms API. The best solution would be to update your forms to RC5 avoid further problems with new releases.
In lieu of that, you should be able to find a fix here (Bootstrapping has changed a little bit since that was written). There is a DeprecatedFormsModule that you can use. In your app.module, import it and add it to the imports array. Like so:
//...
import {DeprecatedFormsModule} from '#angular/common';
#NgModule({
//...
imports: [
//....
DeprecatedFormsModule
],
//...
})

Related

NG6002: Appears in the NgModule.imports of AppModule, but itself has errors

I am upgrading my angualr from 6 to 13.0.2.
When I do ng build , I get an error:
NG6002: Appears in the NgModule.imports of AppModule, but itself has errors 33 export class AdminModule { }
I am sure, Admin module imports doesn't include any components, all components are part of declarations: []
Not sure what the error is related to. I also upgarded angualr material to 13.0.2.
I tried to setenableIvy to false in tsconfig.app.json.
"angularCompilerOptions": {
"enableIvy" : false,
admin.module.ts
import { CUSTOM_ELEMENTS_SCHEMA, NgModule, NO_ERRORS_SCHEMA } from '#angular/core';
import { CommonModule } from '#angular/common';
import {MatRadioModule} from '#angular/material/radio';
import { ReactiveFormsModule, FormsModule } from '#angular/forms';
import { NgxSpinnerModule } from 'ngx-spinner';
import { MatNativeDateModule } from '#angular/material/core';
import { MaterialModule } from 'src/app/material/material.module';
#NgModule({
imports: [
CommonModule,
MaterialModule,
MatRadioModule,
ReactiveFormsModule,
FormsModule,
NgxSpinnerModule,
MatNativeDateModule
],
declarations: [AdminComponent],
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class AdminModule { }
app.module.ts
#NgModule({
declarations: [AppComponent, LoginComponent, HomeComponent],
imports: [
AdminModule,
NgxSpinnerModule,
MatDialog,
NgxSliderModule
],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
,
providers: [
],
bootstrap: [AppComponent],
})
export class AppModule {}

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/storage-angular', data get delete after refresh

I am using angular in my ionic and I have followed everything based on this docs, so im using "#ionic/storage-angular", but my problem is when i refresh, data get deleted. Below is my code.
//app.module
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { RouteReuseStrategy } from '#angular/router';
import { IonicModule, IonicRouteStrategy } from '#ionic/angular';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { HttpClientModule } from '#angular/common/http';
import { IonicStorageModule } from '#ionic/storage-angular';
#NgModule({
declarations: [AppComponent],
entryComponents: [],
imports: [
BrowserModule,
IonicModule.forRoot(),
IonicStorageModule.forRoot(),
AppRoutingModule,
FormsModule,
ReactiveFormsModule,
HttpClientModule
],
providers: [
{
provide: RouteReuseStrategy,
useClass: IonicRouteStrategy,
},
],
bootstrap: [AppComponent]
})
export class AppModule {}
//storage.service
import { Injectable } from '#angular/core';
import { Storage } from '#ionic/storage-angular';
#Injectable({
providedIn: 'root'
})
export class StorageService {
private _storage: Storage | null = null;
constructor(private storage: Storage){
this.init();
}
async init() {
// https://github.com/ionic-team/ionic-storage
// If using, define drivers here: await this.storage.defineDriver(/*...*/);
const storage = await this.storage.create();
this._storage = storage;
}
public set(key: string, value: any) {
this._storage?.set(key, value);
}
public get(key){
return this._storage?.get(key);
}
public clear(){
this._storage.clear();
}
}
//this is how i used the service
await this.storageService.set('loginUser',{id: user.id,userName: user.first_name});

Angular 6 Shared Modules and Sharing Services

I'm having an issue with my Angular 6 app that I'm breaking up into smaller modules. Originally everything was imported into AppModule, and it worked just fine, but it was a giant file and testing was overly complicated.
The issue I'm having is basically creating a shared-module for a few commonly used services across the app. ng build runs fine so it seems to build alright, but when I serve the app I get the error that "ConfigService.foo()" is not a function! I'm obviously doing something wrong to group shared services into a shared module.
Here's some code:
SharedModule
import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest, HttpResponse } from '#angular/common/http';
import { Injectable, OnInit, NgModule } from '#angular/core';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import * as $ from 'jquery';
import { PipeModule } from './pipes/pipes.module';
import { ConfigService } from "./config.service";
#NgModule({
imports: [
PipeModule
],
declarations: [
],
exports: [
PipeModule
],
providers: [
ConfigService
]
})
export class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
ConfigService, {
provide: ConfigService,
useValue: ConfigService
},
],
};
}
}
ConfigService
import {Injectable} from "#angular/core";
import {HttpClient, HttpHeaders, HttpParams, HttpResponse} from "#angular/common/http";
import {HttpObserve} from "#angular/common/http/src/client";
import {Observable, Subject, Observer, BehaviorSubject, throwError} from 'rxjs';
import {Config} from '../shared/config';
import { map, catchError} from 'rxjs/operators';
import * as _ from 'lodash';
#Injectable()
export class ConfigService {
constructor(private httpClient: HttpClient, private config: Config) {
this.config = new Config();
}
ngOnInit() { }
foo() {
console.log("Hack the planet!!! (confgurably)");
}
}
AppModule
import { BrowserModule } from '#angular/platform-browser';
import {APP_INITIALIZER, CUSTOM_ELEMENTS_SCHEMA, NgModule, PipeTransform} from '#angular/core';
import {HttpClient, HttpClientModule} from "#angular/common/http";
import {AppRoutingModule} from './app-routing.module';
import {FormsModule} from "#angular/forms";
import { AppComponent } from './app.component';
import { BannerComponent } from './banner/banner.component';
import { BreadcrumbComponent } from './breadcrumb/breadcrumb.component';
import { SearchComponent } from './search/search.component';
import { SharedModule } from './shared/shared.module';
#NgModule({
declarations: [
AppComponent,
BannerComponent,
BreadcrumbComponent,
SearchComponent
],
imports: [
BrowserModule,
FormsModule,
HttpClientModule,
AppRoutingModule,
SharedModule.forRoot()
],
providers: [
HttpClient
],
bootstrap: [AppComponent]
})
export class AppModule { }
What am I doing wrong with my Shared-Module and injectable services? For reference, I'm using Angularv6.
I just figured it out.
It turns out, when providing your own services in a module, you don't use
{ provide: ConfigService, useValue: ConfigService },
Instead, you simply list the services under providers in your exported module, like this:
export class SharedModule {
static forRoot() {
return {
ngModule: SharedModule,
providers: [
ConfigService
],
};
}
}
Cheers!

Adding new components with default layout

I have just downloaded the angular admin template. Then i add a new component:
ng g n test
When I navigate to the component, the default layout is not applied. I guess it uses the app.component layout. How do you tell the component it should use the default UI?
to add a new componet follow these steps:
create a component-name-routing.module.ts file
create a component-name.module.ts file
create a component-name.component.html file
create a component-name.component.ts file
component-name.component.ts file:
import { Component, OnInit, Input } from "#angular/core";
#Component({
selector: 'app-componentName',
templateUrl: './component-name.component.html',
})
export class NameComponent implements OnInit {}
component-name-routing.module.ts file
import { NgModule } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { NameComponent } from "./component-name.component";
const routes: Routes = [
{
path: '',
component: NameComponent,
data: {
title: 'route title'
},
children: [
{
path: '',
redirectTo: ''
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ComponentNameRoutingModule {}
component-name.module.ts file
// Angular
import { CommonModule } from '#angular/common';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
// Theme Routing
import { ComponentNameRoutingModule } from "./component-name-routing.module";
import { ComponentNameComponent } from "./component-name.component";
#NgModule({
imports: [
ComponentNameRoutingModule,
],
declarations: [
ComponentNameComponent
]
})
export class ComponentNameModule {
constructor() {}
}
all this in a new folder in the views directory and you'll be good to go.