Angular2 Template parser errors - node.js

Env:
Angular2-webpack bolierplate : https://github.com/preboot/angular2-webpack
nodejs 6.3.1 / npm 3.10.3
When I run a karma test an error occurs but It seems works well while server running.
SUMMARY:
✔ 2 tests completed
✖ 1 test failed
FAILED TESTS:
Home Component
✖ should ...
Chrome 55.0.2883 (Mac OS X 10.12.2)
Error: Template parse errors:
'my-searchbar' is not a known element:
1. If 'my-searchbar' is an Angular component, then verify that it is part of this module.
2. If 'my-searchbar' is a Web Component then add "CUSTOM_ELEMENTS_SCHEMA" to the '#NgModule.schemas' of this component to suppress this message. ("d="go_mypage" href="/mypage"><img src="/img/mypage-thin.png"></a>
<div class="fold" id="wrapper">
[ERROR ->]<my-searchbar></my-searchbar>
<span>Home Works!</span>
</div>"): HomeComponent#2:2
...
I have looked at several stack overflow questions or other websites related with this error but They were not very helpful.
app.module.ts
import { NgModule, ApplicationRef } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { HttpModule } from '#angular/http';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { MypageComponent } from './mypage/mypage.component';
import { HomeModule } from './home/home.module';
import { ApiService } from './shared';
import { routing } from './app.routing';
import { removeNgStyles, createNewHosts } from '#angularclass/hmr';
#NgModule({
imports: [
BrowserModule,
HttpModule,
FormsModule,
routing,
HomeModule
],
declarations: [
AppComponent,
MypageComponent
],
providers: [
ApiService
],
bootstrap: [AppComponent]
})
export class AppModule {
constructor(public appRef: ApplicationRef) {}
hmrOnInit(store) {
console.log('HMR store', store);
}
hmrOnDestroy(store) {
let cmpLocation = this.appRef.components.map(cmp => cmp.location.nativeElement);
// recreate elements
store.disposeOldHosts = createNewHosts(cmpLocation);
// remove styles
removeNgStyles();
}
hmrAfterDestroy(store) {
// display new elements
store.disposeOldHosts();
delete store.disposeOldHosts;
}
}
app.component.html
<main>
<router-outlet></router-outlet>
</main>
./home/home.component.html
<a class="route" id="go_mypage" href="/mypage"><img src="/img/mypage-thin.png"></a>
<div class="fold" id="wrapper">
<my-searchbar></my-searchbar>
<span>Home Works!</span>
</div>
./home/home.module.ts
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { RouterModule } from '#angular/router';
import { HomeComponent } from './home.component';
import { SearchbarComponent } from './searchbar.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule
],
declarations: [
HomeComponent,
SearchbarComponent
],
exports: [
HomeComponent,
SearchbarComponent
]
})
export class HomeModule { }
--Update--
./home/searchbar.component.ts
import { Component } from '#angular/core';
#Component({
selector: 'my-searchbar',
templateUrl: './searchbar.component.html',
styleUrls: ['./style/searchbar.component.scss']
})
export class SearchbarComponent {
searchWord: string;
searchTag: string[];
onKey(event: any) {
console.log(event.key);
}
}
home.component.spec.ts
// This shows a different way of testing a component, check about for a simpler one
import { Component } from '#angular/core';
import { TestBed } from '#angular/core/testing';
import { HomeComponent } from './home.component';
describe('Home Component', () => {
const html = '<my-home></my-home>';
beforeEach(() => {
TestBed.configureTestingModule({declarations: [HomeComponent, TestComponent]});
TestBed.overrideComponent(TestComponent, { set: { template: html }});
});
it('should ...', () => {
const fixture = TestBed.createComponent(TestComponent);
fixture.detectChanges();
expect(fixture.nativeElement.children[0].textContent).toContain('Home Works!');
});
});
#Component({selector: 'my-test', template: ''})
class TestComponent { }

The error/warning is explanatory, so pretty much what it says there:
You have created a custom element, <my-searchbar></my-searchbar> which is not a known Angular 2 element, and to suppress the warning add it to schemas in NgModule like so:
schemas: [ CUSTOM_ELEMENTS_SCHEMA ]

Related

Angular 12 sub routes 404 loosing context on refresh

I am having problem with angular 12 sub routes. I can navigate to the sub routes just fine but when I refresh the page I lose context. I am running it locally on the localhost:4200
here is the image of what I am getting in network tab and on the screen when I refresh
enter image description here
here is a link for source code: https://github.com/Stanmozolevskiy/Portfolio
Here is routing component:
import { SinglePortfolioComponent } from './portfolio/single-portfolio/single-portfolio.component';
import { HomeComponent } from './home/home.component';
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { ContactComponent } from './contact/contact.component';
import { AboutComponent } from './about/about.component';
import { PortfolioComponent } from './portfolio/portfolio.component';
const routes: Routes = [
{path: '', component: HomeComponent},
{path: 'contact', component: ContactComponent},
{path: 'about', component: AboutComponent},
{path: 'about/portfolio', component: AboutComponent},
{path: 'portfolio', component: PortfolioComponent},
{path: 'portfolio/:query', component: SinglePortfolioComponent},
];
#NgModule({
imports: [RouterModule.forRoot(routes, {scrollPositionRestoration: 'enabled'})],
exports: [RouterModule]
})
export class AppRoutingModule { }
Here is app module:
import { AngularFireModule } from '#angular/fire';
import { AngularFireFunctionsModule } from '#angular/fire/functions';
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { HomeComponent } from './home/home.component';
import { FontAwesomeModule } from '#fortawesome/angular-fontawesome';
import { ContactComponent } from './contact/contact.component';
import { ReactiveFormsModule } from '#angular/forms';
import { AboutComponent } from './about/about.component';
import { GetintouchComponent } from './getintouch/getintouch.component';
import { PortfolioComponent } from './portfolio/portfolio.component';
import { SinglePortfolioComponent } from './portfolio/single-portfolio/single-portfolio.component';
import { HeaderComponent } from './common/header/header.component';
import { NgbModule } from '#ng-bootstrap/ng-bootstrap';
import { AsideComponent } from './common/aside/aside.component';
import { ParagraphComponent } from './common/paragraph/paragraph.component';
#NgModule({
declarations: [
AppComponent,
HomeComponent,
ContactComponent,
AboutComponent,
GetintouchComponent,
PortfolioComponent,
SinglePortfolioComponent,
HeaderComponent,
AsideComponent,
ParagraphComponent
],
imports: [
AppRoutingModule,
BrowserModule,
FontAwesomeModule,
ReactiveFormsModule ,
AngularFireFunctionsModule,
NgbModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
I will be happy to try any suggestions, thank you in advance!
Solution to this problem:
Change your webserver configurations to match your location strategy or use HashLocationStrategy as follow: imports: [RouterModule.forRoot(appRoutes, {scrollPositionRestoration: 'enabled', useHash: true})]
And please change all href attributes over your code base to routerLink directive as follow:
<a routerLink="/portfolio" class="btn btn-lg edit_hover_class custom-btn">
<fa-icon [icon]="faBriefcase"></fa-icon> My portfolio
</a>
I assume you're talking about the index.html fallback that doesn't work on the production like it works locally while in development.
You can fix your issue by looking at the docs here https://angular.io/guide/deployment#routed-apps-must-fallback-to-indexhtml.
Just know what is your online server and do the solution specific for it.

Angular 9 ngx-translate universal how to load translations before app is loaded?

I have angular universal + pwa + ngx-translate app and now I have a little glitch/bug. When i load my app i can see for like 300-500ms all untranslated texts (keys) like common.back, common.nextand then they change to translation values like next and back.
How to load translation before page load on angular universal ?
This is my setup :
app.module :
export function createTranslateLoader(http: HttpClient) {
return new TranslateHttpLoader(http, './assets/i18n/', '.json');
}
imports: [
...
TransferHttpCacheModule,
HttpClientModule,
TranslateModule.forRoot({
loader: {
provide: TranslateLoader,
useFactory: (createTranslateLoader),
deps: [HttpClient]
}
}),
...
]
app.server.module :
import { NgModule } from '#angular/core';
import { ServerModule, ServerTransferStateModule } from '#angular/platform-server';
import { BrowserModule } from '#angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
#NgModule({
imports: [
AppModule,
ServerModule,
ServerTransferStateModule,
BrowserModule.withServerTransition({ appId: 'autorent' }),
],
bootstrap: [AppComponent],
})
export class AppServerModule { }
app.browser.module :
import { NgModule } from '#angular/core';
import { BrowserModule, BrowserTransferStateModule } from '#angular/platform-browser';
import { AppModule } from './app.module';
import { AppComponent } from './app.component';
import { ServiceWorkerModule } from '#angular/service-worker';
import { environment } from '../environments/environment';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
#NgModule({
imports: [
AppModule,
BrowserModule.withServerTransition({ appId: 'autorent' }),
BrowserTransferStateModule,
ServiceWorkerModule.register('ngsw-worker.js', { enabled: environment.production }),
BrowserAnimationsModule
],
bootstrap: [AppComponent],
})
export class AppBrowserModule { }
If you need another info, which I doubt, just write in comments and I will provide.

Loading a different component.html file from a component.ts file?

I'm new to angular and I was wondering how I could load a different home.component.html file from a method that's inside books.component.ts.
This is my books.component.ts file.
import { Component, OnInit } from '#angular/core';
import {BooksService} from '../books.service';
import {NgForm} from '#angular/forms';
import { Router } from '#angular/router';
#Component({
selector: 'app-books',
templateUrl: './books.component.html',
styleUrls: ['./books.component.css']
})
export class BooksComponent {
constructor(private httpService: BooksService, private router:Router) {
}
status : any;
onSubmit(f: NgForm) {
console.log("AM I HERE AT LEAST");
this.httpService.checkLoginCred(f.value).subscribe(
data => {
// console.log(Object.values(data)[0]);
this.status = Object.values(data)[0];
if(this.status === "Successful"){
var path = "../home/home.component.html";
// console.log($location.path());
//console.log(this.router);
this.router.navigate(['/home']);
console.log("GREAT!");
}
return true;
}
);
}
}
my app.module.ts looks like so:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { BooksComponent } from './books/books.component';
import { HomeComponent } from './home/home.component';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { RouterModule, Routes } from '#angular/router';
#NgModule({
declarations: [
AppComponent,
BooksComponent,
HomeComponent,
],
imports: [
RouterModule.forRoot([
{
path: 'home',
component: HomeComponent
}
]),
BrowserModule,
HttpClientModule,
AppRoutingModule,
FormsModule,
ReactiveFormsModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
my books.component.ts and books.component.html files are in my books directory.
my home.component.ts and home.component.html files are in my home directory
I've attached a screenshot of how my directory structure looks like.
So far I'm trying to use this.router.navigate but I'm not having much luck with that.
Any help would be greatly appreciated!
EDIT
My home.component.ts file looks like so:
import { Component } from '#angular/core';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.css']
})
export class HomeComponent {
constructor() { }
}
As we discussed - here is the solution - hope it works
Add only <router-outlet></router-outlet> on app.compoment.html and using routing try to render the components
Your route should read as
RouterModule.forRoot([
{
path: 'home',
component: HomeComponent
},
{
path: 'book',
component: BookComponent
},
{
path: '',
redirectTo: 'book'
pathMatch: 'full'
}
])
Thus on the initial load your path will match empty and redirect to BookComponent and inside the book component when you navigate it will load the HomeComponent inside the AppComponent html
Hope this might solve your problem - happy coding :-)

Get or fetch API data using Angular (v5) with services and interface?

I am working on Angular with v 5 app. I am doing API fetching and using https://angular.io/guide/http document. But I am unable to see anything in my view.
How can I fix this problem with document provided data?
My folder structure:
https://imgur.com/A03KtDy
There isn't any bug in terminal:
https://imgur.com/a/AEKxv
No issues in console:
https://imgur.com/JaPTvXZ
File: app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
import { NavbarComponent } from './components/navbar/navbar.component';
import { HomeComponent } from './components/home/home.component';
import { DashboardComponent } from './components/dashboard/dashboard.component';
import { ConfigService } from './services/config.service';
const appRoutes: Routes = [
{ path: '', component: HomeComponent },
{ path: 'dashboard', component: DashboardComponent },
];
#NgModule({
declarations: [
AppComponent,
NavbarComponent,
HomeComponent,
DashboardComponent
],
imports: [
BrowserModule,
HttpClientModule,
RouterModule.forRoot(
appRoutes,
{ enableTracing: true } // <-- debugging purposes only
)
// other imports here
],
providers: [ConfigService],
bootstrap: [AppComponent]
})
export class AppModule { }
file: config.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Config } from './config';
import { Observable } from 'rxjs/Observable';
#Injectable()
export class ConfigService {
constructor(private http: HttpClient) { }
configUrl : 'http://localhost:3000/api/get';
getConfig() {
return this.http.get<Config>(this.configUrl)
}
}
file: dashboard.component.ts
import { Component, OnInit } from '#angular/core';
import { ConfigService } from '../../services/config.service';
import { Config } from '../../services/config';
#Component({
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
constructor(private configService : ConfigService) { }
ngOnInit() { }
config: Config;
showConfig() {
this.configService.getConfig()
// clone the data object, using its known Config shape
.subscribe(data => this.config = { ...data });
}
}
file: dashboard.component.html
<ul class="list-group" *ngFor="let config of configs">
<li class="list-group-item list-group-item-dark">{{config.name}}</li>
</ul>
file: config.ts
export interface Config {
name : string
}
I don't see in your code, that you call showConfig() method.
Maybe you forget to add call to ngOnInit() method?
ngOnInit() {
this.showConfig();
}

NgModule routing Angular2 with 2.0.0-rc.5 showing error Unhandled promise rejection Error: Cannot match any routes: ''(…)

I am using NgModule in angular2, 2.0.0-rc.5 but I got the error shim.js:4035 Unhandled promise rejection Error: Cannot match any routes: ''(…). How can I resolve this error.Please help me here is my code.
app/base/app.component.html
<router-outlet></router-outlet>
app/base/app.component.ts
import { Component } from '#angular/core';
import { ROUTER_DIRECTIVES } from '#angular/router';
import { EventService } from '../shared/service/event-service';
#Component({
moduleId: module.id,
selector: 'owb-workbench-app',
templateUrl: 'app.component.html',
providers: [EventService],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent {
}
app/base/app.module.ts
import { provide } from '#angular/core';
import {CommonModule, APP_BASE_HREF} from "#angular/common";
import { disableDeprecatedForms, provideForms } from '#angular/forms/index';
import { enableProdMode } from '#angular/core';
import { bootstrap } from '#angular/platform-browser-dynamic';
import { LocationStrategy, HashLocationStrategy } from '#angular/common';
import { HTTP_PROVIDERS, HttpModule } from '#angular/http';
import { HttpClient } from '../shared/http/base.http';
import { EventService } from '../shared/service/event-service';
import { routing } from './app.routes';
import { DashboardComponent } from '../dashboard/dashboard.component'
import { appRoutingProviders } from './app.routes'
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { NKDatetime } from 'ng2-datetime/ng2-datetime';
#NgModule({
imports: [ BrowserModule, FormsModule,HttpModule,CommonModule,routing,appRoutingProviders],
declarations: [ AppComponent, NKDatetime,DashboardComponent],
exports: [NKDatetime],
bootstrap: [ AppComponent ],
providers: [{ provide: LocationStrategy, useClass: HashLocationStrategy },
{ provide: APP_BASE_HREF, useValue: '<%= APP_BASE %>' },
HTTP_PROVIDERS,EventService,HttpClient]
})
export class AppModule {
}
app/base/app.routes.ts
import { provideRouter, RouterConfig,RouterModule,Routes } from '#angular/router';
import { ModuleWithProviders } from '#angular/core';
import { DashboardRoutes } from '../dashboard/index';
export const routes: RouterConfig = [
...DashboardRoutes
];
export const appRoutingProviders: any[] = [];
export const routing: ModuleWithProviders = RouterModule.forRoot(routes);
app/base/main.ts
import { platformBrowserDynamic } from '#angular/platform-browser-dynamic';
import { AppModule } from './app.module';
const platform = platformBrowserDynamic();
platform.bootstrapModule(AppModule);
app/dashboard/dashboard.component.html
<h1>Hello World Welcome</h1>
app/dashboard/dashboard.component.ts
import { Component } from '#angular/core';
import { ROUTER_DIRECTIVES } from '#angular/router';
import { TopNavComponent } from '../shared/topnav/topnav';
import { SidebarComponent } from '../shared/sidebar/sidebar';
import { RightNavComponent } from '../shared/rightnav/rightnav';
#Component({
moduleId: module.id,
selector: 'dashboard-app',
templateUrl: 'dashboard.component.html',
directives: [ ROUTER_DIRECTIVES, TopNavComponent, SidebarComponent, RightNavComponent ]
})
export class DashboardComponent {}
app/dashboard/dashboard.routes.ts
import { DashboardComponent } from './index';
import { ModuleWithProviders } from '#angular/core';
import { Routes, RouterModule } from '#angular/router';
import { GridViewComponent } from './+gridview/gridview.component'
const appRoutes: Routes = [
{
path: 'dashboard',
component: DashboardComponent
}
];
export const appRoutingProviders: any[] = [
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
app/dashboard/index.ts
/**
* This barrel file provides the export for the lazy loaded DashboardComponent.
*/
export * from './dashboard.component';
export * from './dashboard.routes';
You have to import your routes into the app.module.ts like this. I believe you also need to provide an empty route. In this case, home is my default route, you would change it to be dashboard if that's what your default is.
export const appRoutes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', loadChildren: './app/home/home.module#HomeModule' },
];
export const appRoutingProviders: any[] = [];
My app.module.ts (notice the RouterModule.forRoot(appRoutes) import):
#NgModule({
imports: [ BrowserModule, RouterModule.forRoot(appRoutes), SharedModule.forRoot() ],
declarations: [ AppComponent ],
bootstrap: [ AppComponent ],
providers: [ appRoutingProviders ]
})
export class AppModule {}

Resources