I have created mock service file and I want to display in my html but not really sure how to make it display properly so I'll be really appreciated If I can get any help or suggestion.
<div class="container2">
<div class="header" style="height: 400px">
<div class="content3">
<div>
<h1 class="kpi-title">90,346</h1>. // I'm trying to remove this hard code html
<p class="kpi-des">Users Right Now</p> // and display it from my mock data file.
</div>
<div>
<h1 class="kpi-title">250++l</h1>
<p class="kpi-des">Saved</p>
</div>
<div>
<h1 class="kpi-title">$34.5 mill</h1>
<p class="kpi-des">New User per Week</p>
</div>
</div>
</div>
</div>
TS
import { ProductService } from '../../data/product-suite.service';
export class MaxisProductSuiteComponent {
productService: ProductService[];
ngOnIT(){
}
product-suite.service.ts
export class ProductService {
productsuite: ProductSuite[] = [
{
id: 1,
title: '90,346',
description: 'Users',
},
{
id: 2,
title: '$34.5 mill',
description: 'Saved',
},
{
id: 3,
title: '250++',
description: 'New User per Week',
},
];
}
Please find the below code for your solutions:
create a json file assets folder with name output.json.
{
"result" : [
{
"id": 1,
"title": "90,346",
"description": "Users at Ford"
},
{
"id": 2,
"title": "$34.5 mill",
"description": "Saved for Ford"
},
{
"id": 3,
"title": "250++",
"description": "New User per Week"
},
{
"id": 4,
"title": "64%",
"description": "Users At Ford"
}
]
}
in service file write below code:
import { observable, Observable } from "rxjs";
import { MaxisProductSuite } from "src/Model/model";
import { HttpClient } from '#angular/common/http';
import { Injectable } from "#angular/core";
#Injectable()
export class MaxisProductService {
constructor(private http: HttpClient){}
getAllMaxisps():Observable<MaxisProductSuite> {
return this.http.get<MaxisProductSuite>("./assets/output.json");
}
}
then component file add below code:
import { DOCUMENT } from '#angular/common';
import { Component, Inject, OnInit } from '#angular/core';
import { MaxisProductSuite } from 'src/Model/model';
import { MaxisProductService } from 'src/service/MaxisProductService';
#Component({
selector: 'app-temp',
templateUrl: './temp.component.html',
styleUrls: ['./temp.component.scss']
})
export class TempComponent implements OnInit {
maxisps: MaxisProductSuite[];
public resultData:MaxisProductSuite=null;
constructor(#Inject(DOCUMENT) private document: Document, private service : MaxisProductService) {}
ngOnInit() {
this.service.getAllMaxisps().subscribe((res:MaxisProductSuite) => {
console.log(res);
this.resultData =res;
});
}
}
then HTMl file add below code:
<div *ngFor="let item of resultData?.result">
<div class="header" style="height: 400px">
<h1>{{item.id}}</h1>
<h2>{{item.title}}</h2>
<h3>{{item.description}}</h3>
</div>
add below model in model file
export interface MaxisProductSuite {
result : Result[]
}
export interface Result{
id?: number;
title: string;
description: string;
}
I hope it will help you to get the solution.
happy to HELP!
make your service in module provider or make it injectable "root".
inject the service in your component you want to display data in constructor as a dependency injection.
assign your component variable array with productService.
in your HTML loop about your data array using *ngFor=" let product of products".
use you product value in the interpolation {{ product.id }}.
Related
I have a large JSON file and am trying to randomize and limit the ones that are shown to a list item on HTML. The file has more than 100 items but I would like to show only ten at a time.
I understand doing this by pagination on the server side would be better but this project is to be used locally and for learning purposes only.
This is a project based on this repository. It is basically the same but I would like handle more items by paginating it on the client side(hero-list.component.html). It would be worth checking it out. Otherwise I will paste below the important part.
Can someone help me?
hero.service.ts
import { Injectable } from '#angular/core';
import {
EntityCollectionServiceBase,
EntityCollectionServiceElementsFactory
} from '#ngrx/data';
import { Hero } from '../core';
#Injectable({ providedIn: 'root' })
export class HeroService extends EntityCollectionServiceBase<Hero> {
constructor(serviceElementsFactory: EntityCollectionServiceElementsFactory) {
super('Hero', serviceElementsFactory);
}
}
hero-list.component.ts
import {
Component,
EventEmitter,
Input,
Output,
ChangeDetectionStrategy
} from '#angular/core';
import { Hero } from '../core';
#Component({
selector: 'app-hero-list',
templateUrl: './hero-list.component.html',
changeDetection: ChangeDetectionStrategy.OnPush
})
export class HeroListComponent {
#Input() heroes: Hero[];
#Output() deleted = new EventEmitter<Hero>();
#Output() selected = new EventEmitter<Hero>();
selectHero(hero: Hero) {
this.selected.emit(hero);
}
deleteHero(hero: Hero) {
this.deleted.emit(hero);
}
// trackByHero(hero: Hero): string {
// return hero.id;
// }
trackByHero(_ /* index not used */: number, hero: Hero): string {
return hero.id;
}
}
hero-list.component.html
<ul class="list">
<li
*ngFor="let hero of heroes; trackBy: trackByHero; let i = index"
role="presentation"
>
<div class="card">
<app-card-content
[name]="hero.name"
[description]="hero.description"
></app-card-content>
<footer class="card-footer">
<app-button-footer
class="card-footer-item"
[className]="'delete-item'"
[iconClasses]="'fas fa-trash'"
(clicked)="deleteHero($event)"
label="Delete"
[item]="hero"
></app-button-footer>
<app-button-footer
class="card-footer-item"
[className]="'edit-item'"
[iconClasses]="'fas fa-edit'"
(clicked)="selectHero($event)"
label="Edit"
[item]="hero"
></app-button-footer>
</footer>
</div>
</li>
</ul>
db.json:
{
"heroes": [
{
"id": "HeroAslaug",
"name": "Aslaug",
"description": "warrior queen"
},
{
"id": "HeroBjorn",
"name": "Bjorn Ironside",
"description": "king of 9th century Sweden"
},
{
"id": "HeroIvar",
"name": "Ivar the Boneless",
"description": "commander of the Great Heathen Army"
},
{
"id": "HeroLagertha",
"name": "Lagertha the Shieldmaiden",
"description": "aka Hlaðgerðr"
},
{
"id": "HeroRagnar",
"name": "Ragnar Lothbrok",
"description": "aka Ragnar Sigurdsson"
},
{
"id": "HeroThora",
"name": "Thora Town-hart",
"description": "daughter of Earl Herrauðr of Götaland"
}
]
}
Appreciate it!
A "pagination" if you has all the elements in an array is simply use slice pipe
You has two variables
page:number=0 //the first page is 0
pageSize:number=10
<li *ngFor="let hero of heroes|slice:(page*pageSize):(page+1)*pageSize;
let i = index">
...
</li>
To randomize an array simply use
arrayRandom=this.heroes.map(x=>({ord:Math.random(),data:x}))
.sort((a,b)=>a.ord>b.ord?1:a.ord<b.ord?-1:0)
.map(x=>x.data)
I'm using Ruby on Rails API app for the backend and Angular 6 for the front. this is the json respond I get from the backend:
loclhost3000/courses.json
[
{
id:1,
title:"Introduction",
author:"Dana Inbar",
segments:[
]
},
{
id:2,
title:"Master the ELN",
author:"Dana Inbar",
segments:[
]
},
{
id:3,
title:"Master the Inventory",
author:"Dana Inbar",
segments:[
{
id:1,
unit_id:1,
unit_title:"Introduction",
name:"Lesson 1: Introduction to the inventory module- looking at one collection",
data:"www.video01.com/vid.avi"
},
{
id:2,
unit_id:2,
unit_title:"Inventory Customisation",
name:"Lesson 2: Setting up custom collections",
data:"www.video02.com/vid.avi"
},
{
id:3,
unit_id:2,
unit_title:"Inventory Customisation",
name:"Lesson 3: Adding a custom field",
data:"www.video03.com/vid.avi"
},
{
id:4,
unit_id:2,
unit_title:"Inventory Customisation",
name:"Lesson 4: Creating derived collections",
data:"www.video04.com/vid.avi"
},
{
id:5,
unit_id:2,
unit_title:"Inventory Customisation",
name:"Lesson 5: Using repositories",
data:"www.video05.com/vid.avi"
},
{
id:6,
unit_id:2,
unit_title:"Inventory Customisation",
name:"Quiz",
data:"'[ { "
question 1":"___",
"answers":{
"1":"____",
"2":"____",
"3":"____"
},
"correct_answer":"2"
},
{
"question 2":"___",
"answers":{
"1":"____",
"2":"____"
},
"correct_answer":"1"
}
}
] ' "
}
]
}
]
I have Course model which has many Segments, and Segment is Video or Quiz.
I have course-list, course-detail and course-play components.
I have problem with the course-detail and I want the course-detail page to look like that: course-detail image
I thought I could do functions in course.service which use groupBy with unit_id and unit_title and do two ngFor (or ngFor group) but because I'm new to angular I don't know how is best to implement this.
I'm adding some files from the program which can help:
./courses/course.module
import { NgModule } from '#angular/core';
import { CommonModule } from '#angular/common';
import { RouterModule, Routes } from '#angular/router';
import { MatSidenavModule } from '#angular/material/sidenav';
import { BrowserAnimationsModule } from '#angular/platform-browser/animations';
import { CourseListComponent } from './course-list/course-list.component';
import { CourseDetailComponent } from './course-detail/course-detail.component';
import { CourseService } from './course.service';
import { CoursePlayComponent } from './course-play/course-play.component';
const coursesRoutes: Routes = [
{ path: 'courses', component: CourseListComponent },
{ path: 'courses/:id', component: CourseDetailComponent },
{ path: 'courses/:id/:segment_id', component: CoursePlayComponent }
]
#NgModule({
imports: [
CommonModule,
MatSidenavModule,
BrowserAnimationsModule,
RouterModule.forChild(
coursesRoutes
)
],
declarations: [
CourseListComponent,
CourseDetailComponent,
CoursePlayComponent
],
providers: [
CourseService
]
})
export class CourseModule { }
./courses/course
export interface ICourse {
course_id: number;
title: string;
autor: string;
segments: ISegment[];
}
export interface ISegment {
segment_id: number;
unit_id: number;
unit_title: string;
name: string;
type: string;
data: string;
}
./courses/course.service
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable, throwError } from 'rxjs';
import { map, catchError, retry, groupBy, Filter } from 'rxjs/operators';
import { Course } from './course';
// Inject Data from Rails app to Angular app
#Injectable()
export class CourseService{
constructor(private http: HttpClient) { }
private url = 'http://localhost:3000/courses';
private courseUrl = 'http://localhost:3000/courses.json';
// Handle Any Kind of Errors
private handleError(error: HttpErrorResponse) {
// A client-side or network error occured. Handle it accordingly.
if (error.error instanceof ErrorEvent) {
console.error('An error occured:', error.error.message);
}
// The backend returned an unsuccessful response code.
// The response body may contain clues as to what went wrong.
else {
console.error(
'Backend returned code ${error.status}, ' +
'body was ${error.error}');
}
// return an Observable with a user-facing error error message
return throwError(
'Something bad happend; please try again later.');
}
// Get All Courses from Rails API App
getCourses(): Observable<ICourse[]> {
const coursesUrl = `${this.url}` + '.json';
return this.http.get<ICourse[]>(coursesUrl)
.pipe(
catchError(this.handleError)
);
}
// Get Single Course by id. will 404 if id not found
getCourse(id: number): Observable<ICourse> {
const detailUrl = `${this.url}/${id}` + '.json';
return this.http.get<ICourse[]>(detailUrl)
.pipe(
catchError(this.handleError)
);
}
}
./courses/course-detail/course-detail.component
import { Component, OnInit } from '#angular/core';
import { ActivatedRoute, Router } from '#angular/router';
import { Course } from '../course';
import { CourseService } from '../course.service';
#Component({
selector: 'lg-course-detail',
templateUrl: './course-detail.component.html',
styleUrls: ['./course-detail.component.sass']
})
export class CourseDetailComponent implements OnInit {
course: ICourse;
errorMessage: string;
constructor(private courseService: CourseService,
private route: ActivatedRoute,
private router: Router) {
}
ngOnInit() {
const id = +this.route.snapshot.paramMap.get('id');
this.getCourse(id);
}
// Get course detail by id
getCourse(id: number) {
this.courseService.getCourse(id).subscribe(
course => this.course = course,
error => this.errorMessage = <any>error);
}
onBack(): void {
this.router.navigate(['/courses']);
}
}
./courses/course-detail/course-detail.html
<div id="main" *ngIf="course">
<div class="row" id="image">
<div class="col-lg-8">
<br>
<img src="./assets/images/lg-white.png" class="d-inline-block align-top" alt="">
</div>
</div>
<div class="row" id="header">
<div class="container text-center">
<br>
<h1>{{course.title}}</h1>
<br>
</div>
</div>
<div class="row justify-content-lg-center" id="progress">
<div class="container text-center">
<div class="progress">
<div class="progress-bar bg-white"></div>
</div>
<td>Your Progress</td>
<br><br><br>
</div>
</div>
<div class="row" id="body">
<div class="container">
<br>
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" href="#Curiculum" role="tab" data-toggle="tab">Curiculum</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#About" role="tab" data-toggle="tab">About this course</a>
</li>
</ul>
<br>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane fade in active" id="Curiculum">
<h1>Course Overview</h1>
<br>
<ul *ngFor="let segment of course.segmentsByUnitId">
<ul>
<li id="title">Unit {{segment.unit_id}}: {{segment.unit_title}}</li>
<li>{{segment.name}}</li>
</ul>
</ul>
</div>
<div role="tabpanel" class="tab-pane fade" id="About">
<h1>Course Topics:</h1>
</div>
</div>
<br>
</div>
</div>
</div>
./courses/course-detail/course-detail.sass
$color: #FFFFFF
$bg-col: #5c0099
$prog-size: 10px
#image
background-color: $bg-col
color: $color
#header
background-color: $bg-col
color: $color
#body
background-color: $color
height: 100vh
max-width: initial
display: flex
#title
font-weight: bold
#progress
background-color: $bg-col
color: $color
font-size: $prog-size
.progress
height: 10px
left: 30%
.progress-bar
width: 10%
height: 20px
background-color: transparent
You can do it by using the below groupby pipes.
GroupBy pipe returns an object of a key/value pair.
https://github.com/danrevah/ngx-pipes#groupby
The installation process for ngx-pipes: https://github.com/danrevah/ngx-pipes#installation
Below is how I implemented it for my data:
My data:
tsks = [{
CompletedFlag: true,
ProgressFlag: false,
DueDate:"2014-10-02T13:12:37.027",
Signup: "2014-10-04T11:51:10.137",
ObMilestone: 1,
ObTask: 119,
AssignedToId: 0,
Company: "ABC Corp",
Description: "Lorem Ipsum",
Favourite: null,
FirstName: "Libin",
LastName: "J",
MilestoneName: "Blue",
OnboarderStatus: "Live",
Partner : null
},
{
CompletedFlag: true,
ProgressFlag: false,
DueDate:"2014-10-02T13:12:37.027",
Signup: "2014-10-04T11:51:10.137",
ObMilestone: 1,
ObTask: 119,
AssignedToId: 0,
Company: "ABC Corp",
Description: "Lorem Ipsum",
Favourite: null,
FirstName: "Libin",
LastName: "J",
MilestoneName: "Blue",
OnboarderStatus: "Live",
Partner : null
}];
My code to groupby "MilestoneName"
<div class="row" *ngFor="let task of tsks | groupBy: 'MilestoneName' | pairs">
<div>Group milestone name: {{task[0]}}</div>
<div class="row" *ngFor="let t of task[1]">
<div>Task: {{t.FirstName}}</div>
</div>
</div>
I am trying to loop through json data bellow, to so each element. I need to get down to the details data and then in side that loop through the f1,f2 into a div. I have tried using the index but that didn't work. Also I don't know how many f1,f2 there will be as it is returned from an api
JSON data
{
"data":[
{
"title": "test",
"image": "assets/imgs/test.png",
"date": "22/07/2018 - 19.00",
"location": "test",
"details": [
{
"f1":[
{
"FunctioName": "test",
"Time": "10:00:00"
}
],
"f2":[
{
"FunctioName": "test",
"Time": "11:00:00"
}
]
}
]
}
]
}
HTML
<div *ngFor="let item of card">
<div class="swiper-zoom-container">
<div class="out-card-box">
<h2>Date</h2>
<p>{{item.date}}</p>
<h2>Program</h2>
<div *ngFor="let details of item.details; let i = index">
</div>
</div>
</div>
</div>
TS
import { Component } from '#angular/core';
import { App } from 'ionic-angular';
import { DataService } from "../../services/data";
import { LoginPage } from "../login/login";
import { AngularFireAuth } from "angularfire2/auth";
import { Storage } from "#ionic/storage";
#Component({
selector: 'page-card',
templateUrl: 'card.html',
})
export class CardPage {
card:any;
constructor(private dataservice: DataService, private afAuth:AngularFireAuth, private app:App, private storage:Storage) {
this.dataservice.cardData().subscribe(
data => {
var jsonObj = JSON.parse(data["_body"]);
this.card = jsonObj.data;
console.log(jsonObj.data)
}
);
}
You can create an object which will hold the returned data from the api and you can just navigate the object values.
Example:
export class Class1 {
data: Class2[];
}
export class Class2 {
title: string;
image: string;
date: string;
location: string;
details: Class3[];
}
export class Class3 {
f1: Class4[];
f2: Class4[];
}
export class Class4 {
FunctioName: string;
Time: string
}
#Component({
selector: 'page-card',
templateUrl: 'card.html',
})
export class CardPage {
card:Class1;
constructor(private dataservice: DataService, private afAuth:AngularFireAuth, private app:App, private storage:Storage) {
this.dataservice.cardData().subscribe(
data => {
this.card = data;
}
);
}
then in your component template
<div *ngFor="let item of card.data">
<div class="swiper-zoom-container">
<div class="out-card-box">
<h2>Date</h2>
<p>{{item.date}}</p>
<h2>Program</h2>
<div *ngFor="let details of item.details; let i = index">
<!-- Print the remaining items here -->
</div>
</div>
</div>
</div>
How do I display this specific JSON using *ngFor?
{
"status": 0,
"dallases": [{
"vehicle_id": 17954,
"dallassettings": "3",
"dallasupdated": "False",
"dallas_list": [{
"number": 666111222,
"auth": 3
}, {
"number": 666777888,
"auth": 4
}, {
"number": 123454321,
"auth": 4
}]
}
}
vehicle.service.ts
import { Injectable } from '#angular/core';
import { Http, Headers, RequestOptions, Jsonp, Response } from '#angular/http';
import 'rxjs/add/operator/map';
#Injectable()
export class VehicleService {
constructor(private http: Http) { }
getVehicle() {
return this.http.get('myURL')
.map(res => res.json());
}
}
vehicle.component.ts
import { Component, enableProdMode } from '#angular/core';
import { VehicleService } from './vehicle.service';
enableProdMode();
#Component({
//moduleId: module.id,
selector: 'vehicle-json',
templateUrl: './vehicle.html',
providers: [VehicleService]
})
export class VehicleComponent {
//vehicles: Vehicle[];
vehicles: GeneralVehicle[];
constructor(private vehicleService: VehicleService) {
this.vehicleService.getVehicle().subscribe(vehicle => {
this.vehicles = vehicle;
});
}
}
/*interface Vehicle {
id: number;
title: string;
body: string;
}*/
interface GeneralVehicle {
status: number;
dallases: Vehicle[];
}
interface Vehicle {
vehicle_id: number;
dallassettings: number;
dallasupdated: string;
dallas_list: DallasList[];
}
interface DallasList {
number: number;
auth: number;
}
When I worked on dummy data it was simply, but this JSON structure is more complex. I tried using Pipe, but I'm not sure if I'm using it correctly.
import { Pipe, PipeTransform } from '#angular/core';
#Pipe({ name: 'keys' })
export class VehiclePipe implements PipeTransform {
transform(value, args: string[]): any {
let keys = [];
for (let key in value) {
keys.push(key);
}
return keys;
}
}
That's the *ngFor
*ngFor="let vehicle of vehicles | keys"
I'd like to dislay status once, and then repeat all the dallases (Vehicle[]).
At least you have one error here:
dallassettings: '3' // string
but in your interface you have:
dallassettings: number;
Then if you implement Matthiases implementation, put a *ngIf-statement, since I suspect you get your data async, so view is rendered before data retrieved, which would cause a undefined error.
<div *ngIf="vehicles"> // here!
<h1>{{ vehicles.status }}</h1>
<div *ngFor="let vehicle of vehicles.dallases">
<div>ID: {{vehicle.vehicle_id}}</div>
<div>Settings: {{vehicle.dallassettings}}</div>
<div>Updated: {{vehicle.dallasupdated}}</div>
<div *ngFor="let d of vehicle.dallas_list">
<div>number: {{d.number}}</div>
<div>auth: {{d.auth}}</div>
</div>
</div>
</div>
EDIT your status is undefined, since you you are using the wrong attribute it should be vehicles.status with "s". When I edited this post, I also added the "s" to the answer, so that it would be correct :)
You have to loop through 2 ngFor's:
<div *ngFor="let vehicle of vehicles | keys">
<h1>{{ vehicle.status }}</h1>
<ul *ngFor="let dallas of vehicle.dallases">
<li>{{ dallas | json }}</li> //Show the data you want
</ul>
</div>
vehicles is an object. I see no need to iterate over the keys with the pipe you proposed. You can access the members you need directly. You should iterate over the dalasses property of vehicles - which is an array. Then display the array member as you require. E.g. with a json pipe to get in text format, you you might also implement custom formatting inside the template through properties.
Example:
<div>
<h1>{{ vehicle.status }}</h1>
<div *ngFor="let vehicle of vehicles.dallases">
<div>ID: {{vehicle.vehicle_id}}</div>
<div>Settings: {{vehicle.dallassettings}}</div>
<div>Updated: {{vehicle.dallasupdated}}</div>
<div *ngFor="let d of vehicle.dallas_list">
<div>number: {{d.number}}</div>
<div>auth: {{d.auth}}</div>
</div>
</div>
</div>
I've cloned tour of heroes tutorial product from angular team where demo data is storing in in-memory-data-service.ts. Since my preferred backend is django-rest-framework, I need to link them together.
For example, my heroes are translating from localhost:8000/api/v1/heroes/.
[
{
"name": "Greg",
"id": 5,
},
{
"name": "Krek",
"id": 6,
}
]
What should I do except removing in-memory-data-service.ts to replace heroes list with provided by django backend via json? It would be great if you'll tell me do I need model declaration
export class Hero {
id: number;
name: string;
}
yet if rest-framework gives me full objects structure stored in JSON.
To consume any REST API you have to write a service like below,
import { Injectable } from 'angular2/core';
import { Http, Response } from 'angular2/http';
import { Observable } from 'rxjs/Rx';
export class Hero {
id: number;
name: string;
}
#Injectable()
export class HeroService {
constructor(private _http: Http) { }
getHeroes() {
return this._http.get('api/v1/heroes')
.map((response: Response) => <Hero []>response.json())
}
}
Hope this helps!!