Not an expert at angular far from it. But I’ve been looking deeply and i cant figure out why my other components that call the function types, runs before the constructor. and to solve it where do i put the " echo " function? everything works likes a charm except for the fact that echo is called before types. what or how do i make echo come first to run before any other function. i cant hook it up to the promise because it takes data from another component. i ran a if statement to check if the global variable exist and obviously doesn’t because of the order of processes.
import { Injectable, OnInit, OnDestroy } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http'
import { Observable, of } from "rxjs";
import { Router, ActivatedRoute } from '@angular/router';
import { Location } from '@angular/common/'
import { DataService } from './products.service';
import { BehaviorSubject, Subscription } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable({ providedIn: "root" })
export class CartService implements OnInit, OnDestroy {
public data: any = { "productObjs": [] }
public array: any;
public datap: any;
private sub: Subscription;
//loop up the id if specexist remove thespec if empty remove id
constructor(public dataservice: DataService, private http: HttpClient) {
this.echo()
}
echo() {
let headers = new HttpHeaders();
headers.append('Content-Type', 'application/json');
let prom = new Promise((resolve, reject) => {
this.http.get('../assets/productCategories/products.json', { headers }).toPromise().then((data: any) => {
console.log(data)
var dat = this.datap
resolve(dat)
this.datap = data
return dat
}).then((dat) => { this.nextt(dat) });
})
return this.datap;
}
nextt(datap) {
console.log(datap)
this.datap = datap
}
// types is called from another component and runs before promise finishes
types(type) {
if (this.datap) {
console.log(this.datap)
let that = this
var func = type.func
var rtype = type.type
var arr;
switch (func) {
case "random":
return that.sortByRandom()
break;
case "category":
return that.sortByCategory(rtype)
break;
default: "specific"
return that.sortBySpecific(rtype)
}
console.log(this.array)
console.log(this.array)
console.log(this.array)
console.log(this.datap)
return this.array;
}
}
getArray() {
if (this.datap) {
console.log(this.array)
return this.array
}
}
sortBySpecific(specific) {
let that = this
console.log(that.datap)
var type = that.datap.product.filter(function(objj) {
return objj.type === specific;
})
return type
}
sortByCategory(category) {
let that = this
var type = this.datap.product.filter(function(objj) {
return objj.productCategory === category;
})
return type
}
sortByRandom() {
var cats = []
var picked = []
var sproducts;
let that = this
this.datap.productObjs.forEach((obj) => {
var randomnum2 = Math.floor(Math.random() * this.datap.productObjs.length)
cats.push(obj.category)
})
var randomnum = Math.floor(Math.random() * cats.length)
var selectedCats = this.datap.product.filter(function(objj) {
return objj.productCategory === cats[randomnum];
});
sproducts = selectedCats
var x = sproducts[Math.floor(Math.random() * sproducts.length)]
picked.push(x)
that.array = picked
return picked
}
addToCart(ps, pobj) {
var checkarray = this.data.productObjs.filter(function(obj) {
return obj.productSpec === ps;
});
console.log(checkarray)
if (checkarray.length <= 0) {
this.data.productObjs.push(pobj)
}
}
getItems() {
return this.data.productObjs
}
clearCart() {
this.data.productObjs = []
}
clearProduct(objspec) {
var newarray = this.data.productObjs.filter(function(obj) {
return obj.productSpec !== objspec;
});
this.data.productObjs = newarray;
}
changeInventory() {
//update pricing from inputs
}
checkout() {
this.http.post('http://localhost:4201/api', this.data).subscribe((res) => {
console.log(res)
var json = res
if (json['bool'] === "false") {
//cant check out
// this checks inventory also.
//pop up error problem with pricing.
}
if (json['bool'] === "true") {
//can check out
//neeeds to request paypal to send productinfo and once payment response is succeded send valid, and delete from database.
}
})
}
ngOnInit() {
}
ngOnDestroy() {
this.sub.unsubscribe();
console.log(this.sub)
console.log(this.datap)
}
}
2
Answers
Check this article for how to initialize global data:
https://www.cidean.com/blog/2019/initialize-data-before-angular-app-starts/
BTW, you should never call business logic in a constructor like:
Instead you should call it in the component it need the data, maybe ngOnInit in that component when it is needed.
It is usually recommended to use constructor only for dependency injection mainly. For other initialization consider using Angular life cycle hooks (Difference between constructor and
ngOnInit
).Since you want to run your function
echo()
which gets called from child component you can call it fromngOnInit()
in child component.Then if you have anything that needs to be called from parent to child. You can call child from parent components
ngAfterViewInit()
method. (In your casetypes()
function)