Angular2 service iterate - javascript

I need to get array from JSON API and then iterate it. I still can't understand how it works. Thank you for help.
This is how looks my service.
import {Injectable} from '#angular/core';
import { Http } from "#angular/http";
import "rxjs/Rx";
#Injectable()
export class PlayersService {
roster:Roster[];
constructor(private http: Http){
this.roster = [];
}
getPlayer(id) {
for (let player of this.roster) {
console.log(player["id"]);
}
}
getRoster(season,category) {
this.roster.push(this.http.get("http://API JSON LIST OF ID")
.map(res => res.json()));
}
}
interface Roster {
id:number
}
This how I call it
ngOnInit() {
this.getRoster();
this.getPlayers();
}
Where is the fail please?

This should do what you want:
#Injectable()
export class PlayersService {
roster:Roster[];
constructor(private http: Http){
this.roster = [];
}
getPlayer(id) {
for (let player of this.roster) {
console.log(player["id"]);
}
}
getRoster(season,category) {
return this.http.get("http://API JSON LIST OF ID")
.map(res => res.json())
.do(val => this.roster.push(val)); // the do operator should be used for side effects (eg modifying an existing array)
}
}
ngOnInit() {
this.playerService.getRoster().subscribe(val => this.playerService.getPlayer());
}

Related

Unable to pass data between two components using services

I want to pass the array value from Search component to History component to display the history of the searches done.
I have written the code in this manner -
search-page.component.ts
export class SearchPageComponent implements OnInit {
constructor( private dataService :DataService) { }
githubSearch(username:any){
return new Promise((resolve, reject) => {
this.httpClient.get("----")
.pipe(map(Response => Response))
.subscribe((res: any) => {
this.searchResultObject = res;
this.allSearchResultArray.push(this.searchResultObject);
this.dataService.changeParam(this.allSearchResultArray)
resolve(this.searchResultObject );
});
});
}
passDataToService(){
this.dataService.allPassedData.next(this.allSearchResultArray);
}
}
data.service.ts
export class DataService {
allPassedData: any
constructor() { }
storePassedObject(passedData:any){
this.allPassedData.next(passedData);
}
retrievePassedObject(){
return this.allPassedData;
}
}
history-page.component.ts
export class HistoryPageComponent implements OnInit {
historyData : any = [];
constructor(private dataService: DataService) { }
ngOnInit(): void {
this.historyData = this.dataService.retrievePassedObject()
}
}
I am unable to retrieve data via this designed code.
First create subject in service and make it as observable
data.service.ts
export class DataService {
private allPassedData = new Subject<any>();
allPassedData$ = this.allPassedData.asObservable();
constructor() { }
setPassedData(retrievedData: any) {
this.allPassedData.next(retrievedData);
}
}
Now set the data in the observable
search-page.component.ts
passDataToService() {
this.dataService.setPassedData(this.allSearchResultArray);
}
history-page.component.ts
ngOnInit(): void {
// for retrieval of data in history component
this.dataService.allPassedData$.subscribe((data) => {
this.historyData = data
})
}

How can I display data in the shopping cart in Angular?

I want to display the data from my backend to the front end. It's working but I am making a shopping cart system in Angular using help from a youtube video. I have poor knowledge of Observables and stuff related to it. For the Youtuber, the data is displayed. The only difference between the youtube project and mine is that he is using a fake store API and I am using a database and getting products from the backend.
My cart.component.ts file
import { Component, OnInit } from '#angular/core';
import { CartService } from 'src/services/cart.service';
#Component({
selector: 'app-cart',
templateUrl: './cart.component.html',
styleUrls: ['./cart.component.css']
})
export class CartComponent implements OnInit {
products: any = [];
allProducts: any = 0;
constructor(private cartService: CartService) { }
ngOnInit(): void {
this.cartService.getProductData().subscribe(res => {
this.products = res;
this.allProducts = this.cartService.getTotalAmount();
})
}
removeProduct(item: any) {
this.cartService.removeCartData(item);
}
removeAllProducts() {
this.cartService.removeAllCart();
}
}
My cart.service.ts file
import { Injectable } from '#angular/core';
import { BehaviorSubject } from 'rxjs';
#Injectable({
providedIn: 'root'
})
export class CartService {
cartDataList: any = [];
productList = new BehaviorSubject<any>([]);
constructor() { }
// Get cart data
getProductData() {
return this.productList.asObservable();
}
// Set cart data
setProduct(product: any) {
this.cartDataList.push(...product);
this.productList.next(product);
}
// Add products to cart
addToCart(product: any) {
this.cartDataList.push(product);
this.productList.next(this.cartDataList);
this.getTotalAmount();
console.log(this.cartDataList);
}
// Calculate total amount
getTotalAmount() {
let grandTotal = 0;
this.cartDataList.map((a: any) => {
grandTotal += a.total;
});
}
// Remove product one by one
removeCartData(product: any) {
this.cartDataList.map((a: any, index: any) => {
if (product.id === a.id) {
this.cartDataList.splice(index, 1);
}
})
}
// Empties the whole cart
removeAllCart() {
this.cartDataList = [];
this.productList.next(this.cartDataList);
}
}
I know the problem is in getProductData() function but I don't know how to fix it. Also if you need any other file that may help feel free to ask and yes this is my very first post asking a question.
productList = new BehaviorSubject([]);
getProductData$ = this.productList.asObservable();
do not use this.productList.asObservable() in a function declare it as a variable.

error TS2559: Type 'BookInterface[]' has no properties in common with type 'BookInterface'

Dear I am developing a page with Angular 7 and I am presented with the error TS2559: Type 'BookInterface[]' has no properties in common with type 'BookInterface', I have changed the code but I still can not find the solution, I leave the code below, the error is thrown in the method getListBooks(): this is my file list-books.component.ts
import { BookInterface } from './../../../models/book';
import { DataApiService } from './../../../services/data-api.service';
import { Component, OnInit } from '#angular/core';
import {NgForm} from '#angular/forms';
#Component({
selector: 'app-list-book',
templateUrl: './list-book.component.html',
styleUrls: ['./list-book.component.css']
})
export class ListBookComponent implements OnInit {
constructor(private dataApi: DataApiService) { }
private books: BookInterface = {};
ngOnInit() {
this.getListBooks();
}
getListBooks() {
this.dataApi.getAllBooks().subscribe(books => {
this.books = books;
});
}
onDelete() {
console.log('LIBRO ELIMINADO');
}
}
I also leave the code of my data-api.service.ts from where I call the interface
import { map } from 'rxjs/operators';
import { Observable } from 'rxjs/internal/Observable';
import { Injectable } from '#angular/core';
import { AngularFirestore, AngularFirestoreCollection, AngularFirestoreDocument } from '#angular/fire/firestore';
import { BookInterface } from '../models/book';
#Injectable({
providedIn: 'root'
})
export class DataApiService {
constructor(private afs: AngularFirestore) {
this.bookCollecction = afs.collection<BookInterface>('books');
this.books = this.bookCollecction.valueChanges();
}
private bookCollecction: AngularFirestoreCollection<BookInterface>;
private books: Observable<BookInterface[]>;
private bookDoc: AngularFirestoreDocument<BookInterface>;
private book: Observable<BookInterface>;
getAllBooks() {
return this.books = this.bookCollecction.snapshotChanges()
.pipe(map( changes => {
return changes.map( action => {
const data = action.payload.doc.data() as BookInterface;
data.id = action.payload.doc.id;
return data;
});
}));
}
// metodo que trae un libro a traves de su id
getOneBook(idBook: string) {
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
return this.book = this.bookDoc.snapshotChanges().pipe(map(action => {
if (action.payload.exists === false){
return null;
} else {
const data = action.payload.data() as BookInterface;
data.id = action.payload.id;
return data;
}
}));
}
addBook(book: BookInterface): void {
this.bookCollecction.add(book);
}
updateBook(book: BookInterface): void {
let idBook = book.id;
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
this.bookDoc.update(book);
}
deleteBook(idBook: string): void {
this.bookDoc = this.afs.doc<BookInterface>(`books/${idBook}`);
this.bookDoc.delete();
}
}
The version of typescript that I am currently using is Version 2.7.2, but also update it without solving the problem
You need to change the following:
private books: BookInterface = {};
to:
private books: BookInterface[] = [];

Shared service example Angular 5

I know this question has been asked several times, but problem is that nobody tried to make a some fiddle or show results of code. This is what i have, i need to update values in other component based on value in some other component, but that is not just value,I have call function again in some other component.
I have some component that goes to database and update values, on second hand I have other component that read those values from database from service.
This is example of my code
tasks.service.ts
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { Observable } from 'rxjs';
import 'rxjs/add/operator/catch';
import 'rxjs/add/operator/map';
import { environment } from '../../environments/environment';
import { Tasks } from './tasks';
#Injectable()
export class TasksProvider {
constructor(private http: HttpClient) { }
createNewTask(name: Name) : Observable<any> {
return this.http.post(environment.apiUri + 'tasks', { name, finished: false },
{ responseType: 'text' });
}
updateTask(id: Id, name: Name, finished: boolean) : Observable<any> {
return this.http.put(environment.apiUri + 'tasks/' + id, { name, finished },
{ responseType: 'text' });
}
getAllTasks(): Observable<Tasks[]> {
return this.http.get(environment.apiUri + 'tasks')
.map<any, Tasks[]>(data => data.map(Tasks.fromObject));
}
}
app.component.html
<app-tasks-list></app-tasks-list>
<app-tasks-add-new></app-tasks-add-new>
As you may see I have not child components, that is my main problem
tasks-list.component.ts
import {Component} from '#angular/core';
import { Tasks } from '../services/tasks';
import { TasksProvider } from '../services/tasks.service';
#Component({
selector: 'app-tasks-list',
templateUrl: './tasks-list.component.html',
styleUrls: ['./tasks-list.component.scss']
})
export class TasksListComponent {
tasks: Array<Tasks>;
constructor(private tasksProvider: TasksProvider) { }
ngOnInit() {
this.getTasksList();
}
displayedColumns: string[] = ['id', 'name', 'finished'];
private getTasksList() {
this.tasksProvider.getAllTasks()
.subscribe(tasks => {
this.tasks = tasks;
});
}
public updateCheckboxValue(id: number, name: string, event: any){
this.tasksProvider.updateTask(id, name, event.checked).subscribe(
result => {},
() => {
alert('Something went wrong');
})
}
}
tasks-add-new.component.ts
import { Component, OnInit, Inject } from '#angular/core';
import { MatDialog, MatDialogRef, MAT_DIALOG_DATA } from '#angular/material';
import { Tasks } from '../services/tasks';
import { TasksProvider } from '../services/tasks.service';
export interface DialogData {
name: string;
}
#Component({
selector: 'app-tasks-add-new',
templateUrl: './tasks-add-new.component.html',
styleUrls: ['./tasks-add-new.component.scss']
})
export class TasksAddNewComponent implements OnInit {
ngOnInit() {
}
constructor(public dialog: MatDialog, private tasksProvider: TasksProvider) {}
openDialog(): void {
const dialogRef = this.dialog.open(TasksAddNewDialog, {
width: '250px',
data: {name: this.animal}
});
dialogRef.afterClosed().subscribe(result => {
this.name = result
this.tasksProvider.createNewTask(this.name).subscribe(
result => {},
() => {
alert('Something went wrong');
})
}
}
}
#Component({
selector: 'tasks-add-new-dialog',
templateUrl: 'tasks-add-new-dialog.html'
})
export class TasksAddNewDialog {
constructor(
public dialogRef: MatDialogRef<TasksAddNewDialog>,
#Inject(MAT_DIALOG_DATA) public data: DialogData) {}
onNoClick(): void {
this.dialogRef.close();
}
}
You see now when i call function in tasks-add-new.component.ts like
this.tasksProvider.createNewTask(this.name).subscribe(
result => {},
() => {
alert('Something went wrong');
})
I need to call again function in tasks-list.component.ts
private getTasksList() {
this.tasksProvider.getAllTasks()
.subscribe(tasks => {
this.tasks = tasks;
});
}
Does any body have idea how i can do that the best practice?
On of the possible approach is to use Subjects.
1) Store task list on the service and provide subscribable Subject
private tasks: Array<Task>;
public $tasks: BehaviorSubject<Array<Task>>;
constructor(private http: HttpClient) {
this.$tasks = new BehaviorSubject([]);
...
}
getAllTasks() {
this.http.get(environment.apiUri + 'tasks')
.subscribe(data => {
this.tasks = data;
this.$tasks.next(this.tasks);
});
}
updateTask(params) {
this.http.post(/* params */).subscribe((task) => {
this.tasks = this.tasks.map(t => t.id !== task.id ? t : task);
this.$tasks.next(this.tasks);
});
}
createTask(...) {
// again, do a request, update this.tasks and call $tasks.next
...
}
2) Make one service Subject subscription on the component instead of multiple service methods Observable listeners and update component's list automatically each time the service source has been changed
tasks: Array<Tasks>;
constructor(private tasksProvider: TasksProvider) {
this.tasksProvider.$tasks.subscribe(tasks => this.tasks = tasks);
}
ngOnInit() {
this.tasksProvider.getAllTasks();
}
public updateCheckboxValue(id: number, name: string, event: any){
this.tasksProvider.updateTask(id, name, event.checked);
}

Angular 5 - HTTP Client - converting resp.body to Array

I am trying to get my JSON response from the HttpClient service into an array so that I can loop through using *ngFor in my html. I've tried using "this" to loop through but *ngFor will not accept it. Below is the code for my service.ts component and the main component.ts.
I just need some way to convert an array from "resp.body" into an exportable Array to be used for string interpolation in the html. Any help would be much appreciated!
races.component.ts
import { Component, OnInit } from '#angular/core';
import {Race, RacesService} from './races.service';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'dh-races',
templateUrl: './races.component.html',
providers: [ RacesService ],
styleUrls: ['./races.component.scss']
})
export class RacesComponent {
error: any;
headers: string[];
race: Race;
raceM: any[];
constructor(private racesService: RacesService) {
var raceM = [];
var raceArray = [];
this.racesService.getRaceResponse()
.subscribe(resp => {
raceArray.push(resp.body);
for (let obj of raceArray) {
for (let i in obj) {
raceM.push({
"ID": obj[i].id + ",",
"Date": obj[i].activityStartDate,
"RaceName": obj[i].assetName,
"Website": obj[i].website
})
}
console.log(raceM);
return raceM;
}
});
}
races.service.ts
#Injectable()
export class RacesService {
constructor(private httpClient: HttpClient) { }
getRace() {
return this.httpClient.get(activeApiURL).pipe(
retry(3),
catchError(this.handleError)
);
}
getRaceResponse(): Observable<HttpResponse<Race>> {
return this.httpClient.get<Race>(
activeApiURL, {
observe: 'response'
});
}
To fix the issue, you need to create an interface that matches the data you get from the server, I will call this interface IRace.
Then in the component I will create a variable named races, I will assign the returned value from the server response i.e. resp.body to the races variable.
I'd change the service to look like this:
export interface IRace {
// Your response from server object's properties here like so:
id: Number;
assetName: string;
...
}
export class RacesService {
constructor(private httpClient: HttpClient) { }
getRace() {
return this.httpClient.get(activeApiURL).pipe(
retry(3),
catchError(this.handleError)
);
}
getRaceResponse(): Observable<HttpResponse<Array<Race>>> {
return this.httpClient.get<Array<Race>>(
activeApiURL, {
observe: 'response'
});
}
}
Finally, I'd change the race component to this:
import { Component, OnInit } from '#angular/core';
import { Race, RacesService, IRace } from './races.service';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'dh-races',
templateUrl: './races.component.html',
providers: [ RacesService ],
styleUrls: ['./races.component.scss']
})
export class RacesComponent {
error: any;
headers: string[];
races: IRace[];
constructor(private racesService: RacesService) {
this.racesService.getRaceResponse()
.subscribe(resp => {
this.races = resp.body;
});
}
}
I hope this helps.

Categories