Issue
In my Angular 7 app I have two sibling componentns... configurator component and custom stepper component. In configurator component I have some functions that get data from my API and calculate some values... I want to show the calculated value in custom stepper component.
I have created a service called price-weight service but am unsure which code to move where and how to get the values from that service in the custom stepper component.
configurator.component.ts has this code:
constructor(
public dialog: MatDialog,
private httpClient: HttpClient,
private _snackBar: MatSnackBar,
public priceWeight: PriceWeightService,
) { }
ngOnInit() {
const httpOptions = {
headers: new HttpHeaders({
'Auth-token': 'somerandomstring',
})
};
this.httpClient.get(`${environment.apiUrl}`, httpOptions).subscribe(
(data) => {
this.parseData(data);
console.log('Izbrana konfig.:', this.selected);
this.getTotalWeight();
this.getTotalPrice();
},
(error) => {
console.log('Error', error);
}
);
// this.getData();
this.openDialog();
}
parseData(data: any) {
console.log(data);
this.data = data;
let i = 0;
for (const step of data.steps) {
if (step.subcategory.length === 0) {
this.selected[i] = {
ident: step.ident,
name: step.name,
optionIdent: step.options[0].ident,
optionName: step.options[0].name,
optionPrice: step.options[0].price,
optionWeight: step.options[0].weight,
categoryType: step.category_type,
};
}
i++;
}
}
findElement(item) {
return Object.values(this.selected).filter(e => e.optionIdent === item.ident).length > 0;
}
setOptionSelected(item, step) {
if (Object.values(this.selected).filter(e => e.ident === step.ident).length > 0) {
const selectedKey = Object.values(this.selected).findIndex(x => x.ident === step.ident);
this.selected[selectedKey] = {'ident': step.ident, 'name': step.name, 'optionIdent': item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
} else {
const totalLength = Object.keys(this.selected).length;
this.selected[totalLength] = {'ident' : step.ident, 'name': step.name, 'optionIdent' : item.ident, 'optionName' : item.name, 'optionPrice' : item.price, 'optionWeight' : item.weight, 'categoryType' : step.category_type};
}
this.getTotalWeight();
this.getTotalPrice();
}
setOptionSubCatSelected(item, step, subcategory) {
if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {
const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
if (index !== -1) {
this.selected.splice(index, 1);
}
} else {
if (Object.values(this.selected).filter(e => e.ident === subcategory.ident).length > 0) {
const selectedKey = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident);
this.selected[selectedKey] = {
'ident': subcategory.ident,
'name': subcategory.name,
'optionIdent': item.ident,
'optionName' : item.name,
'optionPrice' : item.price,
'optionWeight' : item.weight,
'categoryType' : subcategory.category_type
};
} else {
const totalLength = Object.values(this.selected).length;
this.selected[totalLength] = {
'ident' : subcategory.ident,
'name': subcategory.name,
'optionIdent' : item.ident,
'optionName' : item.name,
'optionPrice' : item.price,
'optionWeight' : item.weight,
'categoryType' : subcategory.category_type
};
}
}
this.getTotalWeight();
this.getTotalPrice();
}
setCheckSelected(item, step, subcategory) {
if (step.category_type === 1 && (Object.values(this.selected).filter(e => e.ident === subcategory.ident && e.optionIdent === item.ident).length > 0 ) ) {
const index: number = Object.values(this.selected).findIndex(x => x.ident === subcategory.ident && x.optionIdent === item.ident);
if (index !== -1) {
this.selected.splice(index, 1);
}
} else {
const totalLength = Object.keys(this.selected).length;
this.selected[totalLength] = {
'ident' : subcategory.ident,
'name': subcategory.name,
'optionIdent' : item.ident,
'optionName' : item.name,
'optionPrice' : item.price,
'optionWeight' : item.weight,
'categoryType' : subcategory.category_type
};
}
this.getTotalWeight();
this.getTotalPrice();
}
getTotalPrice() {
let totalPrice = 0;
console.log('Price start:', totalPrice);
for (const item of this.selected) {
if (item.optionPrice) {
totalPrice += Number(item.optionPrice);
console.log('Price now:', totalPrice);
}
}
console.log('Total price:', totalPrice);
return totalPrice;
}
getTotalWeight() {
let totalWeight = 0;
console.log('Weight start:', totalWeight);
for (const item of this.selected) {
if (item.optionWeight) {
totalWeight += Number(item.optionWeight);
console.log('Weight now:', totalWeight);
}
}
console.log('Total weight:', totalWeight);
return totalWeight;
}
Code in custom-stepper.component.ts is this:
import { Component } from '@angular/core';
import { CdkStepper } from '@angular/cdk/stepper';
import { PriceWeightService } from '../_services/price-weight.service';
@Component({
selector: 'app-custom-stepper',
templateUrl: './custom-stepper.component.html',
styleUrls: ['./custom-stepper.component.scss'],
providers: [{provide: CdkStepper, useExisting: CustomStepperComponent}],
})
export class CustomStepperComponent extends CdkStepper {
constructor(
public priceWeight: PriceWeightService
){}
onClick(index: number): void {
this.selectedIndex = index;
}
}
and this is the html of custom-steppr how I wan't to show the values:
<footer>
<mat-toolbar>
<h2>Step {{selectedIndex + 1}}/{{_steps.length}}</h2>
<span class="fill-space"></span>
<p class="mat-small"><strong>Total weight:</strong> {{ totalWeight | number: '1.2':'sl' }} KG</p>
<span class="fill-space"></span>
<p class="mat-small"><strong>Total price:</strong> {{ totalPrice | currency: 'EUR':'symbol':'4.2-2':'sl' }}</p>
<span class="fill-space"></span>
<button [ngClass]="selectedIndex > 0 ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)>_steps.length" cdkStepperNext>Begin configuration</button>
<button [ngClass]="selectedIndex == 0 ? 'noBtn': ''" mat-raised-button color="secondary" class="naslednji-korak" [disabled]="selectedIndex == 0" cdkStepperPrevious>Previous step</button>
<button [ngClass]="selectedIndex == 0 ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)==_steps.length" cdkStepperNext>Next step</button>
<button [ngClass]="(selectedIndex + 1)<_steps.length ? 'noBtn': ''" mat-raised-button color="primary" class="naslednji-korak" [disabled]="(selectedIndex + 1)<_steps.length" (click)="reset()">Submit order</button>
</mat-toolbar>
</footer>
I have added the service with this code:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class PriceWeightService {
weight = 0;
}
Solution
Create properties in the service:
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class PriceWeightService {
weight = 0;
}
Inject the service into both components
constructor(private priceWeight: PriceWeightService){}
Set a property on the service from you configurator component like this
this.priceWeight.weight = this.getTotalWeight();
Services are singleton, so this will update that property for any other components that have injected the service.
To use the service property in your stepper component, either make the service public, or create a getter.
constructor(public priceWeight: PriceWeightService){}
<p>{{priceWeight.weight}}</p>
or
constructor(private priceWeight: PriceWeightService){}
get weight(){
return this.priceWeight.weight;
}
<p>{{weight}}</p>
The specific code you need
service
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class PriceWeightService {
price = 0;
weight = 0;
}
configurator.component.ts
this.httpClient.get(`${environment.apiUrl}`, httpOptions).subscribe(
(data) => {
this.parseData(data);
console.log('Izbrana konfig.:', this.selected);
this.priceWeightService.weight = this.getTotalWeight();
this.priceWeightService.price = this.getTotalPrice();
},
(error) => {
console.log('Error', error);
}
);
custom-stepper.component.ts
constructor(private priceWeight: PriceWeightService){}
get totalWeight(){
return this.priceWeight.weight;
}
get totalPrice(){
return this.priceWeight.price;
}
Answered By - Chris Hamilton
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.