Currently i'm developing a web app which shows the Golden State Warriors (Basketball Team) Roster.
My main goal consists in filtering all players by position.
Positions are numbers ordered from 1 to 5.
My question would be: which could be the way to transform my http get request in order to obtain the point-guards (position === 1) ??
roster-data.service.ts
import { Injectable } from '#angular/core';
import { Player } from "../models/player";
import { environment } from "../../environments/environment";
import {HttpClient, HttpErrorResponse} from '#angular/common/http';
import {Observable, throwError} from 'rxjs';
import {catchError, map, filter } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class RosterDataService {
private readonly devURL = environment.url;
constructor(private http: HttpClient) {
}
jSON_Server_ReadPointGuards():Observable<Player[]> {
return this.http.get<Player[]>(`${this.devURL}/roster_GoldenStateWarriors`).pipe(
map(players => players.filter((player:Player) => player.position === 1)
),
catchError(this.handleError)
);
}
And then my interface
player.ts
export interface Player {
fullName: string,
shirtNumber: string,
position: number,
height: string,
weight: number,
points: number,
rebounds: number,
assists: number,
blocks: number,
steals: number,
imageFile: string,
imageDescrip: string
}
players.component.ts
import { Component, OnInit, isDevMode } from '#angular/core';
import { RosterDataService } from "../../services/roster-data.service";
import { Player } from "../../models/player";
import { imgRoute } from "../../services/img-route.service";
#Component({
selector: 'app-players',
templateUrl: './players.component.html',
styleUrls: ['./players.component.scss'],
providers: [RosterDataService]
})
export class PlayersComponent implements OnInit {
public imageLocation:string;
public bases!: Player[];
public escoltas!: Player[];
public aleros!: Player[];
public alaPivots!: Player[];
public pivots!: Player[];
public getPlayers: Player[] = [];
constructor(private _rosterDataService: RosterDataService) {
this.imageLocation = imgRoute.path;
}
ngOnInit(): void {
this.dev_SuscribeAllPointGuards();
// this.dev_SuscribeAllShootingGuards();
// this.dev_SuscribeAllSmallForwards();
// this.dev_SuscribeAllPowerForwards();
// this.dev_SuscribeAllCenters();
}
dev_SuscribeAllPointGuards(){
this._rosterDataService.jSON_Server_ReadPointGuards().subscribe(
pointguards => {
this.bases = pointguards;
}
);
}
}
players.component.html
<section>
<article>
<h4 id="pointGuard">{{ "players.firstTitle" | translate }}</h4>
<div class="gallery">
<div [routerLink]="'/'+(base.fullName | removespaces)+'/'+base.shirtNumber" *ngFor="let base of bases;">
<figure><img src="{{imageLocation + base.imageFile}}" alt="{{base.imageDescrip}}" title="{{base.imageDescrip}}"></figure>
<section>
<h5>{{base.fullName}}</h5>
<h6>{{base.shirtNumber}}</h6>
<h6>{{base.points}}</h6>
<h6>{{base.rebounds}}</h6>
<h6>{{base.assists}}</h6>
<h6>{{base.blocks}}</h6>
<h6>{{base.steals}}</h6>
</section>
</div>
</div>
</article>
</section>
Related
if I add an object to the objectListDrawArea array outside of the original class, it will be added, but my * ngFor cannot find the object. I have absolutely no idea how to solve it, should I use Observable, if so can you leave an example in the comments? Thank you
ao-bar.component.ts
import { AoBarService } from './ao-bar.service';
import { DrawAreaComponent } from '../../../draw-area/draw-area/draw-area.component';
#Component({
selector: 'app-ao-bar',
templateUrl: './ao-bar.component.html',
styleUrls: ['./ao-bar.component.sass']
})
export class AoBarComponent implements OnInit {
objectsList: object[] = new Array();
showObjectsList: boolean;
drawAreaComponent: DrawAreaComponent = new DrawAreaComponent();
constructor(private service: AoBarService) {
this.service.getObject(this.objectsList);
}
ngOnInit() {
console.log(this.objectsList, ' AoBarComponent');
}
private onShowObjectsList() {
this.showObjectsList = !this.showObjectsList;
}
public onDragEnd(event: DragEvent): void {
console.log('drag end', event);
if (this.drawAreaComponent.onDragEnter) {
for (let object of this.objectsList) {
if (object.name == event.path[0].nextElementSibling.innerText) {
object.settings.x = event.x;
object.settings.y = event.y;
this.drawAreaComponent.createObject(object);
}
}
}
}
}
draw-area.component.ts:
import { Component, OnInit } from '#angular/core';
import { CdkDragEnd } from '#angular/cdk/drag-drop';
#Component({
selector: 'app-draw-area',
templateUrl: './draw-area.component.html',
styleUrls: ['./draw-area.component.sass']
})
export class DrawAreaComponent implements OnInit {
objectsList: object[] = new Array();
constructor() {
}
ngOnInit() {
}
public onDragEnter(event: DragEvent): boolean {
console.log('drag enter', event);
return true;
}
public onDragEnd(event: CdkDragEnd): void {
console.log(event);
}
public createObject(objectToCreate: object): void {
this.objectsList.push(objectToCreate);
console.log(`Aktuelle Liste: ${this.objectsList}`);
}
}
draw-area.component.html :
<div id="DrawAreaComponent">
<div
class="example-boundary"
(dragenter)="onDragEnter($event)"
>
<div
id="ContainerObject"
*ngFor="let object of objectsList | async"
cdkDragBoundary=".example-boundary"
cdkDrag
(cdkDragEnded)="onDragEnd($event)"
>
<img id="ImgObject" [src]="object.imgUrl">
</div>
</div>
</div>
this is a change detection issue.
instead of this.objectsList.push(objectToCreate);
use this.objectsList = [...this.objectsList, objectToCreate]; it will work.
read about change detection.
Component HTML
<div>
<select name="cos">
<option selected="selected" >Wybierz kino</option>
<option *ngFor="let kino of kina "[value]="kino.id">{{ kino.name }} | {{ kino.id }}</option>
</select>
<div *ngIf="kino.id" *ngFor="let kin of kina.cinemaProgramme.programmeItems" style="color:white;">
{{ kin.movie.title }}
</div>
</div>
Component TS
import { Component, OnInit } from '#angular/core';
import { ProgrammeService } from '../programme.service';
import { Time } from '#angular/common';
#Component({
selector: 'app-repertuar',
templateUrl: './repertuar.component.html',
styleUrls: ['./repertuar.component.css']
})
export class RepertuarComponent implements OnInit {
film: CinemaProgramme[];
repertuar: CinemaProgramme[];
kina: Cinema[];
programy: Array<ProgrammeItems> = [];
getCinemaProgramme(): void {
this.programmeService.getCinemaProgramme().
subscribe(repertuar => this.repertuar = repertuar);
}
getCinema(): void {
this.programmeService.getCinema().
subscribe(kina => this.kina = kina);
}
getCinemaPrograme(): void {
this.programmeService.getCinemaPrograme().
subscribe(film => this.film = film);
}
getRepertuar(): void {
this.programmeService.getRepertuar().
subscribe(programy => this.programy = programy);
}
constructor(private programmeService: ProgrammeService) { }
ngOnInit() {
this.getCinemaProgramme();
this.getCinema();
}
}
export interface Cinema {
name: string;
id: number;
cinemaProgramme: CinemaProgramme;
}
export interface CinemaProgramme {
id: number;
programmeItems: Array<ProgrammeItems> ;
}
export interface ProgrammeItems {
movie: Movie;
hours: Date[];
}
export interface Movie {
id?: number;
title?: string;
director?: string;
length?: Time;
description?: string;
}
Service
import { Injectable } from '#angular/core';
import { of, Observable } from 'rxjs';
import { ProgrammeItems, CinemaProgramme, Cinema } from './repertuar/repertuar.component';
import { HttpClient } from '#angular/common/http';
#Injectable({
providedIn: 'root'
})
export class ProgrammeService {
private url = 'http://localhost:8080/';
getCinemaPrograme(): Observable<CinemaProgramme[]> {
return this.http.get<CinemaProgramme[]>(this.url + 'cinema/getAll');
}
getCinemaProgramme(): Observable<CinemaProgramme[]> {
return this.http.get<CinemaProgramme[]>('http://localhost:8080/programme/get/6');
}
getCinema(): Observable<Cinema[]> {
return this.http.get<Cinema[]>('http://localhost:8080/cinema/getAll');
}
getRepertuar(): Observable<Array<ProgrammeItems>> {
return this.http.get<Array<ProgrammeItems>>(this.url + 'programme/getAll');
}
constructor(private http: HttpClient) { }
}
I was thinking about getting the cinema id (cinema_name)
which would be in [value] = "kina.id"
and apply it to dependencies in displaying a given repertoire but even JSON's properties from the second ngfora are not displayed at all: / How should I do it ?? ;/
And sorry for my english.
You second div (second ngFor) is not displayed because you have *ngIf="kino.id" but kino is only defined inside
<option *ngFor="let kino of kina "[value]="kino.id">{{ kino.name }} | {{ kino.id }}</option>
and each option created has it's own kino.id. But outside the option kino is undefined. So your condition is false. If you want to check the value selected in your div (second *ngFor) you should declare a variable in your ts a variable to keep the selected id. So something like:
film: CinemaProgramme[];
repertuar: CinemaProgramme[];
kina: Cinema[];
programy: Array<ProgrammeItems> = [];
selectedKinoId: "";
_______________________
and than use it in your selector like this:
<select [(ngModel)]="selectedKinoId" name="cos">...</select>
and your condition in the div with the second *ngIf would become:
<div *ngIf="selectedKinoId"
Please also note that kina.cinemaProgramme does not exists since kina is an array of Cinema elements. So you will probably need a function to get the cinema by id.
I would recoment adding a function like this to your Component TS:
getCinemaById(id){
for(let kin of kina) {
if(kin.id == id) {
return kin;
}
}
}
So div with the second *ngIf would become
<div *ngIf="selectedKinoId" *ngFor="let kin of getCinemaById(selectedKinoId).cinemaProgramme.programmeItems" style="color:white;">
{{ kin.movie.title }}
</div>
I have an array with 4 items, and 4 buttons on a dashboard. I want to assign item1 with button1, and item2 with button2 etc. Right now it displays 4 buttons for each "hero" for a total of 16 buttons. I tried {{hero.name[2]}} and similar things but that just grabs letters and not the actual array items. I would appreciate any help.
dashboard.component.html
<h3>Calibrations</h3>
<div class="grid grid-pad">
<a *ngFor="let hero of heroes" [routerLink]="['/detail', hero.id]">
<button style ="min-height: 70px" (click)="gotoClick(1)">{{hero.name}}</button>
<button style ="min-height: 70px" (click)="gotoClick(2)">{{hero.name}}</button>
<button style ="min-height: 70px" (click)="gotoClick(3)">{{hero.name}}</button>
<button style ="min-height: 70px" (click)="gotoClick(4)">{{hero.name}}</button>
</a>
</div>
dashboard.component.ts
import { Component, OnInit } from '#angular/core';
import { Hero } from '../hero.class';
import { HeroService } from '../hero.service';
import { StepService } from '../step.service';
#Component({
moduleId: module.id,
selector: 'app-dashboard',
templateUrl: './dashboard.component.html',
styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {
heroes: Hero[] = [];
constructor(private heroService: HeroService, private _stepService: StepService, private _teststepService: StepService) { }
ngOnInit() {
this.heroService.getHeroes().subscribe(heroes => this.heroes = heroes);
}
private test: number;
gotoClick(value: number){
this._stepService.setTest(value);
this._teststepService.apiURL();
}
}
hero.service.ts
import { Injectable } from '#angular/core';
import { Headers, Http, Response } from '#angular/http';
import { Hero } from './hero.class';
import { Observable } from "rxjs/Rx";
#Injectable()
export class HeroService {
private headers = new Headers({'Content-Type': 'application/json'});
private heroesUrl = 'api/heroes'; // URL to web api
constructor(private http: Http){ }
getHeroes(): Observable<Hero[]> {
return this.http.get(this.heroesUrl)
.map(response => response.json().data as Hero[]);
}
getHero(id: number): Observable<Hero> {
const url = `${this.heroesUrl}/${id}`;
return this.http.get(url)
.map(response => response.json().data as Hero);
}
}
You can use the built-in index property of *ngFor:
<div class="grid grid-pad">
<a *ngFor="let hero of heroes; let i = index;" [routerLink]="['/detail', hero.id]">
<button style ="min-height: 70px" (click)="gotoClick(i)">{{hero?.name}</button>
</a>
</div>
Documentation: https://angular.io/docs/ts/latest/api/common/index/NgFor-directive.html
This is the first component where i am pushing those things into array named items and i am trying to get it in the second component through service
import { Component } from '#angular/core';
import { FormBuilder, FormControl } from '#angular/forms';
import {AppService} from '../second/app.service';
import { Router } from '#angular/router';
import { Http,Response } from '#angular/http';
import { routing, appRoutingProviders } from '../app.route';
import { Validators } from '#angular/forms';
import {BrowserModule} from '#angular/platform-browser';
#Component({
selector: 'first-app',
templateUrl:"../app/src/component/first/app.firstpage.html"
})
export class FirstComponent
{
data:any;
public items=[];
public edited=false;
public city=false;
public dateCon=false;
inputForm: FormGroup;
Select: FormControl;
Selectt: FormControl;
dat:FormControl;
constructor(private appservice:AppService,builder: FormBuilder, router:Router)
{
this.appservice.getData().subscribe(res=>{this.data=res.json()});
console.log(this.data);
this.Select = new FormControl('', [
Validators.required
]);
this.Selectt = new FormControl('', [
Validators.required
]);
this.dat = new FormControl('', [
Validators.required
]);
this.inputForm = builder.group({
Select: this.Select,
Selectt: this.Selectt,
dat: this.dat
});
this.router=router;
this.appservice=appservice;
}
ngOnInit(){
this.appservice.getData()
}
onclick(a,b) {
console.log(this.data);
let sel1=this.inputForm.value.Select;
let sel2=this.inputForm.value.Selectt;
let sel3=this.inputForm.value.dat;
console.log(sel3);
console.log(sel1);
console.log(sel2);
console.log(this.data.bus.length);
for(let i=0;i<this.data.bus.length;i++){
if((this.data.bus[i].from==sel1)&&(this.data.bus[i].to==sel2))
{
this.items.push(this.data.bus[i]);
}
}
this.appservice.setData(this.items);
}
if((sel1!="")&&(sel2!="")&&(sel3!="")&&(sel1!=sel2))
{
this.router.navigate(['/sec-component']);
}
else if((sel1=="")&&(sel2=="")&&(sel3==""))
{
this.edited=true;
}
if((sel1==sel2)&&((sel1!="")&&(sel2!="")))
{
this.edited=false;
this.city=true;
}
else
{
this.city=false;
}
if(sel1!=sel2)
{
this.edited=false;
}
if(sel3=="")
{
this.dateCon=true;
}
else
{
this.dateCon=false;
}
}
}
This is the second component to which i am passing this array and i need to get that printed over there and each properties to be accessed rather than the entire stuff.
import { Component } from '#angular/core';
import {AppService} from '../first/first.service';
#Component({
template:
`
<h1>second component</h1>
<h1>second component</h1>
<p >{{myName}}</p>
`
})
export class SecondComponent {
constructor(private appservice: AppService)
{
this.appservice=appservice;
this.myName=appservice.getVal();
}
}
This is the service page where i am returning the values
import {Component, Injectable,Input,Output,EventEmitter} from '#angular/core'
import { Http, Response } from '#angular/http';
export interface myData
{
name:any;
}
#Injectable()
export class AppService
{
sharingData: myData={name:""};
constructor(private http:Http){ }
getData()
{
return this.http.get('./app/src/component/busDet.json')
}
setData(i)
{
console.log('save data function called' + i + this.sharingData.name);
this.sharingData.name=i;
console.log(this.sharingData.name);
}
getVal()
{
console.log(this.sharingData.name);
return this.sharingData.name;
}
}
I am getting the output as object.object
I am not able to get the values with in the JSON in the next component.
I am trying to do a simple import but I am getting a massive stack trace issue.
I have tried searching everywhere for issues related to this but to me, the stack trace doesn't provide much information.
EDIT: I have tried setting it a variable that isn't fetched from Firebase and it works fine. I guess the question now is how do I handle this information from Firebase so that it loads when it is ready.
Here are the relevant files:
main.ts:
import { bootstrap } from '#angular/platform-browser-dynamic';
import {AppComponent} from './app.component';
import { HTTP_PROVIDERS } from '#angular/http';
bootstrap(AppComponent, [HTTP_PROVIDERS]);
player.services.ts:
import { Injectable } from '#angular/core';
import {Player} from "../classes/player";
#Injectable()
export class PlayerService {
player: Player;
getPlayer()
{
return Promise.resolve(this.player);
}
createPlayer(uid: string, name: string, firebaseRef: Firebase)
{
this.player = {
'uid': uid,
'name': name,
'level': 1,
'maxHealth': 100,
'health': 100,
'maxEnergy': 50,
'energy': 50,
'fun': 1,
'skill': 1,
'knowledge': 1
}
firebaseRef.child('players').child(uid).set(this.player);
}
setPlayer(player: Player)
{
this.player = player;
}
}
app.component.ts
import { Component, OnInit } from '#angular/core'
import { PlayerDetailComponent } from './components/player-detail.component';
import {PlayerService} from "./services/player.service";
import {FirebaseEventPipe} from "./firebasepipe";
import {Player} from "./classes/player";
#Component({
selector: "my-app",
templateUrl: 'app/views/app.component.html',
directives: [PlayerDetailComponent],
providers: [PlayerService],
pipes: [FirebaseEventPipe]
})
export class AppComponent implements OnInit{
title = "title";
authData: any;
private firebaseUrl: string;
private firebaseRef: Firebase;
private loggedIn = false;
player: Player;
constructor(private playerService: PlayerService) {
this.firebaseUrl = "https://!.firebaseio.com/";
this.firebaseRef = new Firebase(this.firebaseUrl);
this.firebaseRef.onAuth((user) => {
if (user) {
this.authData = user;
this.loggedIn = true;
}
});
}
getPlayer() {
this.firebaseRef.once("value", (dataSnapshot) => {
if (dataSnapshot.child('players').child(this.authData.uid).exists()) {
this.firebaseRef.child('players').child(this.authData.uid).once("value", (data) => {
this.player = data.val();
this.playerService.setPlayer(this.player);
console.log(this.player);
});
} else {
this.playerService.createPlayer(this.authData.uid, this.getName(this.authData), this.firebaseRef);
this.playerService.getPlayer().then(player => this.player);
console.log(this.player);
}
});
}
ngOnInit() {
this.getPlayer();
}
authWithGithub() {
this.firebaseRef.authWithOAuthPopup("github", (error) =>
{
if (error) {
console.log(error);
}
});
}
authWithGoogle() {
this.firebaseRef.authWithOAuthPopup("google",(error) =>
{
if (error) {
console.log(error);
}
});
}
getName(authData: any) {
switch (authData.provider) {
case 'github':
return authData.github.displayName;
case 'google':
return authData.google.displayName;
}
}
}
player-detail.component.ts
import { Component, Input, OnInit } from '#angular/core';
import { Player } from '../classes/player';
#Component({
selector: "player-details",
templateUrl: "app/views/player-detail.component.html",
styleUrls: ['app/style/player-detail.component.css'],
})
export class PlayerDetailComponent implements OnInit{
#Input() player: Player;
ngOnInit() { console.log(this.player)}
}
app.component.html
<nav class="navbar navbar-default">
<div class="container">
<ul class="nav navbar-nav">
<li class="navbar-link">Home</li>
</ul>
</div>
</nav>
<div class="jumbotron" [hidden]="loggedIn">
<div class="container">
<h1>Angular Attack Project</h1>
<p>This is a project for the Angular Attack 2016 hackathon. This is a small project where set goals
in order to gain experience as a player and person. In order to begin, please register with on of the following services</p>
<button class="btn btn-social btn-github" (click)="authWithGithub()"><span class="fa fa-github"></span>Sign Up With Github </button>
<button class="btn btn-social btn-google" (click)="authWithGoogle()"><span class="fa fa-google"></span>Sign Up With Github </button>
</div>
</div>
<player-details [player]="player" [hidden]="!loggedIn"></player-details>
player-detail.component.html
<div id="player" class="panel panel-default">
<div id="player-stats" class="panel-body">
<img id="player-image" class="img-responsive" src="../app/assets/images/boy.png"/>
<div class="health-bars">
<div class="health-bar">HEALTH:<br/><progress value="{{ player.health }}" max="{{ player.maxHealth }}"></progress></div>
<div class="energy-bar">ENERGY:<br/><progress value="{{ player.energy }}" max="{{ player.maxEnergy }}"></progress></div>
<div class="player-attributes"><span class="fa fa-futbol-o player-attr fun">: {{ player.fun }} </span><span class="fa fa-cubes player-attr skill">: {{ player.skill }}</span> <span class="fa fa-graduation-cap player-attr knowledge">: {{ player.knowledge }}</span></div>
</div>
</div>
</div>
In your service you don't have to return with the promise. You can use a getter
private player: Player;
get CurrentPlayer()
{
return this.player;
}
Then in your component:
getPlayer() {
this.firebaseRef.once("value", (dataSnapshot) => {
if (dataSnapshot.child('players').child(this.authData.uid).exists()) {
this.firebaseRef.child('players').child(this.authData.uid).once("value", (data) => {
this.playerService.setPlayer(this.player);
console.log(this.player);
});
} else {
this.playerService.createPlayer(this.authData.uid, this.getName(this.authData), this.firebaseRef);
console.log(this.player);
}
});
ngOnInit() {
this.player = this.playerService.CurrentPlayer();
this.getPlayer();
}
If you setup the reference first, it should automatically update. You can also throw an *ngIf player-details component definition in the DOM and only show it once the player object isn't undefined.
Edit
Just saw someone else posted about *ngIf prior to me, so if that is the solution, please mark theirs.
The player variable was undefined when the PlayerDetailComponent was loaded therefore there was no such object as player.
To fix this, OnChanges can be implemented like this:
import { Component, Input, OnChanges, SimpleChange } from '#angular/core';
import { Player } from '../classes/player';
import {HealthBarComponent} from "./health-bar.component";
import {ChecklistComponent} from "./checklist.component";
#Component({
selector: "player-details",
templateUrl: "app/views/player-detail.component.html",
styleUrls: ['app/style/player-detail.component.css'],
directives: [HealthBarComponent, ChecklistComponent],
})
export class PlayerDetailComponent implements OnChanges{
#Input()
player: Player;
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
}
}
and then we can add *nfIf="player" within the template to ensure that the player object isn't blank before loading the element.