Angular 2: *ngIf, Template parse errors, {{}} works well - html

I am using Angular version 2.4.1 and I have error 'Template parse errors:(…)' when I'm running this code:
Component:
import {Component} from '#angular/core';
import {SharedData} from '../student/student.data';
#Component({
moduleId: module.id.toString(),
selector: 'sd-toolbar',
templateUrl: 'toolbar.component.html',
providers: [SharedData]
})
export class ToolbarComponent {
var: boolean;
var2: number;
constructor(service: SharedData){
this.var = service.getLog();
this.var2 = service.getId();
console.log(this.var);
}
}
Module code:
import {NgModule } from '#angular/core';
import {CommonModule} from '#angular/common';
import {ToolbarComponent} from './toolbar.component';
import { BrowserModule } from '#angular/platform-browser';
#NgModule({
imports: [
CommonModule
],
declarations: [ ToolbarComponent ],
})
class MyComponentModule {}
and Html code:
<nav class="site-menu">
<ul>
<li>
<div *ngIf="!var">
<div class="notifications">
<a class="notifications__toggle" data-toggle="notifications" href="#notifications">
<span class="num">4</span>
</a>
<div class="notifications__list">
<ul>
<li>Ny notifikation på 287530</li>
</ul>
</div>
</div>
</div>
</li>
{{var2}} in html shows good, but it's problem with that *ngIf, can you guys help me with this problem?

Related

angular 6 with jsonplaceholder , opening posts/${id} after clicking button

I am working on a dummy app with jsonplaceholder, I am getting all posts but i am unable to get post with dynamic id like posts/${id}. How can i achieve this. kindly help.
I am having basic generate angular app.
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { HttpClientModule } from '#angular/common/http';
import { AppComponent } from './app.component';
#NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [AppComponent],
bootstrap: [AppComponent]
})
export class AppModule { }
app.component.html
<h1>{{title}}</h1>
<!-- -->
<main *ngIf="!some; else elseBlock">
<section *ngFor="let dt of data">
<aside>ID: <span id="id">{{dt.id}}</span></aside>
<aside>Title: {{dt.title}}</aside>
<button (click)="linkto()">click to view</button>
<br>
<hr>
</section>
</main>
<ng-template #elseBlock>
<section>
<aside>ID: {{data2.id}}</aside>
<aside>Title: {{data2.title}}</aside>
<aside>Body: {{data2.body}}</aside>
<button (click)="linkto()">back</button>
<br>
<hr>
</section>
</ng-template>
app.component.ts
import { Component } from '#angular/core';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent {
title = 'app';
constructor(private http : HttpClient){
this.showPost();
}
data :any = [];
id: any;
data2 :any = {};
some: boolean;
showPost() {
this.http.get('https://jsonplaceholder.typicode.com/posts')
// clone the data object, using its known Config shape
.subscribe(data => {
console.log('**************',data);
this.data = data
});
}
linkto(){
this.showPost2();
this.some = !this.some;
}
showPost2() {
this.http.get(`https://jsonplaceholder.typicode.com/posts/${id}`)
.subscribe(data2 => {
this.data2 = data2;
});
}
}
i am also interested if is there any shorter way to do this?
like simple on one page . i am making get requests but after this i will be making post, put , patch and delete too. on app.component.html page itself.
You should send id from html to component using linkto(dt.id)
Then you can use that id as a parameter in your component methods.
HTML:
<main *ngIf="!some; else elseBlock">
<section *ngFor="let dt of data">
<aside>ID: <span id="id">{{dt.id}}</span></aside>
<aside>Title: {{dt.title}}</aside>
<button (click)="linkto(dt.id)">click to view</button>
<br>
<hr>
</section>
</main>
<ng-template #elseBlock>
<section>
<aside>ID: {{data2.id}}</aside>
<aside>Title: {{data2.title}}</aside>
<aside>Body: {{data2.body}}</aside>
<button (click)="linkto(dt.id)">back</button>
<br>
<hr>
</section>
</ng-template>
Component:
linkto(id){
this.showPost2(id);
this.some = !this.some;
}
showPost2(id) {
this.http.get(`https://jsonplaceholder.typicode.com/posts/${id}`)
.subscribe(data2 => {
this.data2 = data2;
});
}

Nav toolbar and side nav not coming in other components

I have searched for this question a lot but still unable to find the solution.
In my app, the after successful logging in the page shows the side nav and toolbar. When an item(component) is clicked in side nav, the respective component is displayed but toolbar does not and also side nav.
Here are the files I have written,
app.component.html
<div *ngIf="user_id !== undefined">
<app-applayoutmodel></app-applayoutmodel>
</div>
<div class="container">
<router-outlet></router-outlet>
</div>
app.component.ts,
import { Component, Input, OnInit } from '#angular/core';
import { Router, NavigationExtras, ActivatedRoute , Params} from '#angular/router';
import * as globals from '../app/pages/models/myGlobals';
import { LoginService } from '../serviceProviders/loginservice';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
title = 'app';
user_id: string = undefined;
constructor(
private route: ActivatedRoute,
private router: Router,
private loginservice: LoginService ) {}
ngOnInit() {
if ( this.router.url.length === 1) {
this.user_id = undefined;
} else {
console.log('Url ' + this.router.url);
const urlParam = this.router.parseUrl(this.router.url).queryParams['property_id'];
this.loginservice.user_id = urlParam;
this.user_id = this.loginservice.user_id;
}
// subscribe to router event
}
}
app-routing.module.ts,
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { LoginComponent } from './pages/login/login.component';
import { AppComponent } from './app.component';
import { DashboardComponent } from '../app/pages/dashboard/dashboard.component';
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: '', redirectTo: '/login', pathMatch: 'full'},
{path: 'applayout', component: AppComponent},
{path: 'dashboard', component: DashboardComponent}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }
applayoutmodel.component.html,
<div class="page">
<mat-toolbar color="primary" class="toolbar">
<div>
<button class="menuButton" mat-icon-button (click)="sidenav.toggle()"><mat-icon>menu</mat-icon></button>
<span class="companyName">YAANA</span>
</div>
</mat-toolbar>
<mat-sidenav-container class="sideContainer" fullscreen autosize style="top: 80px !important;">
<mat-sidenav #sidenav mode="push" opened="false" class="sideNav">
<mat-nav-list>
<nav class="menuItems">
<a routerLink="/dashboard">Dashboard</a>
</nav>
<nav class="menuItems">
<a routerLink="/login">Login</a>
</nav>
</mat-nav-list>
</mat-sidenav>
</mat-sidenav-container>
</div>
applayoutmodel.component.ts,
import { Component, OnInit } from '#angular/core';
import { Router, NavigationExtras } from '#angular/router';
#Component({
selector: 'app-applayoutmodel',
templateUrl: './applayoutmodel.component.html',
styleUrls: ['./applayoutmodel.component.scss']
})
export class ApplayoutmodelComponent implements OnInit {
constructor(private router: Router) { }
ngOnInit() {
}
}
Here are the output screens,
After successful loggin in, the firt page is,
When I click dashboard which is listed inside side nav, the output screen is,
But what I need even though after clicking dashboard item inside side nav, the dashboard component view should be displayed along with toolbar and side nav button just like in output screen one.
Please help me to solve this issue, I am not getting any ideas.
Please try this:
- in your app.component.html remove ngIf:
<div>
<app-applayoutmodel></app-applayoutmodel>
</div>
<div class="container">
<router-outlet></router-outlet>
</div>
- in your app-routing.module.ts you need to put your dashboard component as child component of AppComponent like this:
const routes: Routes = [
{path: 'login', component: LoginComponent},
{path: '', redirectTo: '/login', pathMatch: 'full'},
{ path: 'applayout',
component: AppComponent,
children: [
{path: 'dashboard', component: DashboardComponent }
]
}
];
#NgModule({
imports: [
CommonModule,
RouterModule.forRoot(routes)
],
exports: [
RouterModule
],
declarations: []
})
export class AppRoutingModule { }
This is because you want your applayoutmodel component always to be availible even if you click on 'dashboard'. This is where your router-outlet jumps-in:
he renders your Dashboard component in place of tag, and preserves applayoutmodel component rendered and intact. Please try this and let me know...

Route navigation in Angular4 not reacting

I have made an Angular4 component and the page that it generates has a button to navigate to another page. I don't get any errors and the pageUrl changes but the content of the page stays the same.
Here is my code:
app.component.ts
import { Component } from '#angular/core';
import { Router } from "#angular/router";
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
constructor(private router: Router){}
username = "";
password = "";
log = function () {
if (this.username != "" && this.password != "") {
console.log(this.username + " " + this.password);
this.router.navigate(['/dashboard']);
}
}
}
app.module.ts
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { RouterModule } from '#angular/router';
import { FormsModule, ReactiveFormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import { DashboardComponent } from './dashboard/dashboard.component';
#NgModule({
declarations: [
AppComponent,
DashboardComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{
path: 'dashboard',
component: DashboardComponent
}
]
)
],
providers: [],
bootstrap: [AppComponent],
})
export class AppModule {
}
app.component.html
<div class="outer-container">
<div class="inner-container">
<div class="centered-content">
<div class="center"><img src="../favicon.png"></div>
<label class="addText"> Username: </label><input [(ngModel)]
="username" class="addText"><br>
<label class="addText"> Password: </label><input [(ngModel)]
="password" type="password" class="addText"><br>
<div class="center"><button (click) ="log()">Log in</button></div>
</div>
</div>
</div>
To achieve what you want, have the app.component only to include the router-outlet:
#Component({
selector: 'app-root',
template: `
<!-- Views go here-->
<router-outlet></router-outlet>
`,
})
export class AppComponent { }
And then have a separate component for each view you want. So in your case you'd want to create a LoginComponent, which would then route to the DashboardComponent from there.
PS Of course this is expandable and you could add a header component tag in the AppComponent html, or whatever else and so on and so on. But just to showcase this simple use case.
you need to specify where to display the DashboardComponent
add this tag to tell angular the location where to display the component results from router
<router-outlet></router-outlet>

how to implement ng2-dragula in angular 2

how to implement ng2-dragula in angular 2.
My code is shared below,
****viewer.component.ts****
import { Component, Input, Output, EventEmitter } from '#angular/core';
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/Rx';
import { ImageViewerService } from '../services/http.services';
import { Dragula,DragulaService } from 'ng2-dragula/ng2-dragula';
#Component({
moduleId: module.id,
selector: 'viewer',
directives: [Dragula],
viewProviders: [DragulaService],
providers: [ImageViewerService, DragulaService],
templateUrl: 'viewer.component.html',
})
export class ViewerComponent {
#Output() click = new EventEmitter();
http: Http;
url: string;
obj: any;
getData: string;
postData: string;
users: any;
firtsImageToBind: any;
tile: number;
tableVisible: boolean;
status: { isopen: boolean } = { isopen: false };
localImageViewerService: ImageViewerService;
localDragulaService: DragulaService;
constructor(http: Http, imageViewerService: ImageViewerService,
localDragulaService: DragulaService) {
this.users = [1];
this.http = http;
this.localImageViewerService = imageViewerService;
this.localDragulaService = localDragulaService;
this.imageReceivedFromWebAPI();
}
Ok so a quick example showing how to implement dragula into Angular2 project first install via npm:
npm install ng2-dragula dragula --save
Next import into module:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HttpModule } from '#angular/http';
import { AppComponent } from './app.component';
import {DragulaModule} from 'ng2-dragula/ng2-dragula'; // Here
#NgModule({
declarations: [
AppComponent
],
imports: [
DragulaModule, // Here
BrowserModule,
FormsModule,
HttpModule
],
providers: [],
bootstrap: [AppComponent]
})
export class AppModule { }
Inside app.component.html you do this.
<div>
<div class='wrapper'>
<div class='container' [dragula]='"first-bag"'>
<div>You can move these elements between these two containers</div>
<div>Moving them anywhere else isn't quite possible</div>
<div>There's also the possibility of moving elements around in the same container, changing their position</div>
</div>
<div class='container' [dragula]='"first-bag"'>
<div>This is the default use case. You only need to specify the containers you want to use</div>
<div>More interactive use cases lie ahead</div>
<div>Make sure to check out the <a href='https://github.com/bevacqua/dragula#readme'>documentation on GitHub!</a></div>
</div>
</div>
</div>
run the project, and you'll be able to drag the text up and down i.e changing its order.
Example specified above is from dragula github page.

Angular2 rc5 and Electron Error - Cannot resolve component using

I learning how to use angular2 with electron.Currently i am using the the latest angular rc5 and the latest version of electron.I decided to use the official angular tutorial (Tour of heroes). I had no major problems till i got to routing.I had to make some little changes for routing to work eg in index.html instead of using for support with electron i had to use .I am also using webpack and angular2-materialize.
My problem is when i click one of the heroes it shows the error stated in the title, here is a picture :
error image
here is the code for this particular component (dashboard.component)
html (dashboard.component.html): `
<h3>Top Heroes</h3>
<div class="grid grid-pad">
<div *ngFor="let hero of heroes" (click)="gotoDetail(hero)" class="col-1- 4">
<div class="module hero">
<h4>{{hero.name}}</h4>
</div>
</div>
</div>
`
typescript(dashboard.component.ts):
import {Component, OnInit} from '#angular/core';
import {Hero} from './hero';
import {HeroService} from './hero.service';
import {Router} from '#angular/router';
#Component({
selector: 'my-dashboard',
templateUrl: './dashboard.component.html'
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private router: Router,private heroService: HeroService){}
ngOnInit(): void {
this.heroService.getHeroes().then(heroes => this.heroes = heroes.slice(1,5));
}
gotoDetail (hero: Hero): void
{
let link = ['/detail',hero.id];
this.router.navigate(link);
}
}
app.module.ts :
import { NgModule } from '#angular/core';
import { BrowserModule } from '#angular/platform-browser';
import { FormsModule } from '#angular/forms';
import { AppComponent } from './app.component';
import {MaterializeDirective} from "angular2-materialize";
import {HeroDetailComponent} from './hero-detail.component';
import {HeroService} from './hero.service';
import {HeroesComponent} from './heroes.component';
import {routing} from './app.routing';
import {DashboardComponent} from './dashboard.component';
#NgModule({
imports: [
BrowserModule,
FormsModule,
routing,
],
declarations: [
AppComponent,HeroDetailComponent,MaterializeDirective,HeroesComponent,DashboardComponent
],
providers: [HeroService],
bootstrap: [ AppComponent ],
})
export class AppModule { }
index.html:
<html>
<head>
<base href="">
<title>First App</title>
<!--<link href="http://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">-->
<link href="../icons/icon.css" rel="stylesheet">
<link href="../node_modules/materialize-css/dist/css/materialize.css" rel="stylesheet" />
<link href="../css/styles.css" rel="stylesheet">
</head>
<body>
<myapp></myapp>
<script src="../build/common.js"></script>
<script src="../build/angular2.js"></script>
<script src="../build/app.js"></script>
</body>
main.ts:
import {platformBrowserDynamic} from '#angular/platform-browser-dynamic';
import {AppModule} from './app.module';
platformBrowserDynamic().bootstrapModule(AppModule);
app.routing.ts:
import {ModuleWithProviders} from '#angular/core';
import {Routes, RouterModule} from '#angular/router';
import {HeroesComponent} from './heroes.component';
import {DashboardComponent} from './dashboard.component';
import {HeroDetailComponent} from './hero-detail.component';
const appRoutes: Routes = [
{
path: 'heroes',
component: HeroesComponent
},
{
path: 'dashboard',
component: DashboardComponent
},
{
path: '',
redirectTo: '/dashboard',
pathMatch: 'full'
},
{
path: 'detail/:id',
component:'HeroDetailComponent'
}
];
export const routing: ModuleWithProviders = RouterModule.forRoot(appRoutes);
app.component.ts:
import { Component } from '#angular/core';
#Component({
selector: 'myapp',
template: `
<nav>
<div class="nav-wrapper">
{{title}}
<ul id="nav-mobile" class="left">
<li><a routerLink="/heroes">Heroes</a></li>
<li><a routerLink="/dashboard">Dashboard</a></li>
</ul>
</div>
</nav>
<router-outlet></router-outlet>
`
})
export class AppComponent {
title = 'Tour of Heroes';
}
hero-detail.component.ts :
import {Component, Input, OnInit} from '#angular/core';
import {ActivatedRoute, Params} from '#angular/router';
import {HeroService} from './hero.service';
import {Hero} from './hero';
#Component({
selector: 'my-hero-detail',
templateUrl: './hero-detail.component.html'
})
export class HeroDetailComponent implements OnInit {
#Input()
hero: Hero;
constructor(private heroService: HeroService, private route: ActivatedRoute)
{
}
ngOnInit(): void
{
this.route.params.forEach((params: Params) => {
let id = +params['id'];
this.heroService.getHero(id)
.then(hero => this.hero = hero);
});
}
goBack(): void {
window.history.back();
}
}
hero-detail.component.html
<div *ngIf="hero">
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
<label>name: </label>
<input [(ngModel)]="hero.name" placeholder="name"/>
</div>
<button (click)="goBack()">Back</button>
</div>
Thank You
You should be have your component name without '(single quote) in component option of route. As you already have imported HeroDetailComponent there in app.routing.ts(rotue configuration).
{
path: 'detail/:id',
component: HeroDetailComponent //<-- removed quote from here
}
I observed that you are having file protocol while asking for template, it means you haven't hosted your application on server.
Please host your application on server(lite server would also work), so that template would ask
over http protocol instead of file.