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

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;
});
}

Related

How to route in angular without displaying both components

I'm trying to use Angulars router to route from my landing component to my "Events" component via a button click on the landing page. Upon this button click, I want to display only the Events component, however when I click the button (or append "/events" to the end of the URL), the Events component displays below the landing component, displaying both components.
app.component.html:
<app-landing></app-landing>
landing.component.html:
<div class="landing-container">
<div class="landing-search">
<p> selected city: {{ selectedCity }}</p>
<button mat-raised-button color="secondary" (click)="getCombinedResponses()"><a routerLink="/events">Search</a></button>
</div>
</div>
<router-outlet></router-outlet>
app-routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LandingComponent } from './landing/landing.component';
import { VenueCardsComponent } from './venues/venues.component';
const appRoutes: Routes = [
{ path: 'events', component: VenueCardsComponent }
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [ RouterModule ]
})
export class AppRoutingModule {}
Your router-outlet needs to be in app.component.html in your case and you need to have a route for your landing page as well.
app.component.html:
<router-outlet></router-outlet>
landing.component.html:
<div class="landing-container">
<div class="landing-search">
<p> selected city: {{ selectedCity }}</p>
<button mat-raised-button color="secondary" (click)="getCombinedResponses()"><a routerLink="/events">Search</a></button>
</div>
</div>
app-routing.module.ts:
import { NgModule } from '#angular/core';
import { RouterModule, Routes } from '#angular/router';
import { LandingComponent } from './landing/landing.component';
import { VenueCardsComponent } from './venues/venues.component';
const appRoutes: Routes = [
{ path: '', component: LandingComponent },
{ path: 'events', component: VenueCardsComponent }
];
#NgModule({
imports: [RouterModule.forRoot(appRoutes)],
exports: [ RouterModule ]
})
export class AppRoutingModule {}

Errorcan't bind *ngFor

I'm a beginner in Angular and I'm trying to create an application that looks like CapitalistAdventure. But I have an error that I can't resolve and would like to receive some help please. First of all here is how looks my app:
The error is located at the app.component.html and it says:
Can't bind to 'product' since it isn't a known property of 'app-product'.
1. If 'app-product' is an Angular component and it has 'product' input, then verify that it is part of this module.
2. If 'app-product' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '#NgModule.schemas' of this component to suppress this message.
3. To allow any property add 'NO_ERRORS_SCHEMA' to the '#NgModule.schemas' of this component.
Here is the code that I have for my app.component.html:
<h1><span id="WorldName">{{world.name}}WORLDNAME</span></h1>
<!--<span id="WorldImage"><img [attr.src]="server+world.logo"/></span>-->
<div class="UserData">
<div class="Money">
<span id="MoneyName">Money:</span>
<br>
<!--<span [innerHTML]="world.money | bigvalue"></span>-->
<span>$</span>
</div>
<div class="Buy">
<span id="BuyName">Buy</span>
</div>
<div class="ID">
<span id="MoneyName">ID :</span>
</div>
</div>
<div class="Game">
<div class="UpgradeContainer">
<div class="Upgrade" (click)="setModal('Unlock')">Unlocks</div>
<div class="Upgrade" (click)="setModal('Cash')">Cash</div>
<div class="Upgrade" (click)="setModal('Angels')">Angels</div>
<div class="Upgrade" (click)="setModal('Managers')">Managers</div>
<div class="Upgrade" (click)="setModal('Investors')">Investors</div>
</div>
<div class="ProductContainer">
<app-product *ngFor="let product of products" [product]="product"></app-product>
</div>
</div>
My app.module.ts:
import { BrowserModule } from '#angular/platform-browser';
import { NgModule } from '#angular/core';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { RestserviceService } from 'src/app/restservice.service';
import { HttpClientModule } from '#angular/common/http';
import { ProductComponent } from './product/product.component';
import { BigvaluePipe } from './bigvalue.pipe';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import {MatProgressBarModule} from '#angular/material/progress-bar';
#NgModule({
declarations: [
AppComponent,
ProductComponent,
BigvaluePipe,
],
imports: [
BrowserModule,
AppRoutingModule,
HttpClientModule,
BrowserAnimationsModule,
MatProgressBarModule,
],
providers: [RestserviceService],
bootstrap: [AppComponent]
})
export class AppModule { }
My app.component.ts:
import { Component } from '#angular/core';
import { RestserviceService } from './restservice.service';
import { World, Product, Pallier } from './world';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'AngularProject';
world: World = new World();
server: String;
products = [1,2,3,4,5,6];
modal: String;
constructor(private service: RestserviceService) {
this.server = service.getServer();
service.getWorld().then(world => { this.world = world; });
}
setModal(value: String){
this.modal = value;
}
}
My product.component.html:
<div class="Product">
<div class="ProductInfo">
<img onclick="alert('Production lancé'), starFabrication() " class="ProductImage" src="./assets/Avatar.jpg">
<!--<mat-progress-bar mode="determinate" class="ProgressBar" [value]="progressbarvalue"></mat-progress-bar>-->
<div class="ProductNumber">ProductNumber</div>
<div class="ProductPrice">ProductPrice</div>
</div>
</div>
And finally my product.component.ts:
import { Component, OnInit, Input } from '#angular/core';
import { Product } from 'src/app/world';
#Component({
selector: 'app-product',
templateUrl: './product.component.html',
styleUrls: ['./product.component.css']
})
export class ProductComponent implements OnInit {
product: Product;
#Input()
set prod(value: Product){
this.product = value;
}
constructor() { }
ngOnInit(): void {
}
}
I'm precising but I'm on Angular 9.
Thanks in advance to anybody who would take the time to help me.
You need to move the #Input() decorator to bind to the product variable. Try the following
export class ProductComponent implements OnInit {
#Input()
product: Product;
constructor() { }
ngOnInit(): void {
}
}
OR
If you wish to use the #Input() decorator with the setter, then you need to bind to it's name in the template.
Controller
export class ProductComponent implements OnInit {
product: Product;
#Input()
set prod(value: Product){
this.product = value;
}
constructor() { }
ngOnInit(): void { }
}
Template
<app-product *ngFor="let product of products" [prod]="product"></app-product>

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...

how to navigate(redirect) to another page in Angular?

I'm trying to redirect to another page(Page-II) when a button clicked but unfortunately that another page component loads on the same page(Page-I). Here what I tried so far :
app.component.html
<button (click)="register()"
mat-raised-button class="searchButton" type="button">Register</button>
<button (click)="profile()"
mat-raised-button class="searchButton" type="button">Profile</button>
<router-outlet></router-outlet>
app-routing.module.ts
const routes: Routes = [{
path : 'register',
component : RegisterComponent
},
{
path : 'profile',
component : ProfileComponent
}];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
app.component.ts
import { Component , OnInit } from '#angular/core';
import { Router } from '#angular/router';
#Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'app';
constructor(private router: Router ) {}
register = function () {
location.pathname = ('/register');
};
profile = function(){
this.router.navigateByUrl('/profile');
};
ngOnInit() {
}
}
Note: I know that profile loads on same page but trying to redirect register.html when register button clicks on another page.
Can you try this:
register() {
this.router.navigate(['/register']);
}

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>