Problem get unstructured object - Angular - javascript

i am student
Why does it return undefined?
It is an object I need to perform destructuring to obtain only two values.
I can get complete array, but trying to unstructured it returns undefined.
service
getLastCashMov(): Observable<CashMov> {
const url = `${this.API_URL}/last_cashmov`
return this.http.get<CashMov>(url)
}
component
getLastCashMov() {
this.cashMovsService.getLastCashMov()
.subscribe(({balanceARS, balanceUSD}) =>
{ this.lastCashMovs = {balanceARS, balanceUSD};
console.log(balanceARS, balanceUSD)
}, error => {
console.log(error)
})
}
return
when using
getLastCashMov() {
this.cashMovsService.getLastCashMov()
.subscribe((res) =>
{ this.lastCashMovs = res;
console.log(this.lastCashMovs)
}, error => {
console.log(error)
})
}
return
SOLUTION
getLastCashMov() {
this.cashMovsService.getLastCashMov()
.subscribe(([{balanceARS, balanceUSD}]) =>
{ this.lastCashMovs = {balanceARS, balanceUSD};
console.log(this.lastCashMovs)
}, error => {
console.log(error)
})
}
SERVICE
getLastCashMov(): Observable<CashMov[]> {
const url = `${this.API_URL}/last_cashmov`
return this.http.get<CashMov[]>(url)
}

We can't Unstructure array of object for some keys. we need to update and filter keys through map or filter
Here is the code :
getLastCashMov() {
this.cashMovsService.getLastCashMov()
.subscribe((responseArray) => {
let filteredArray = responseArray.map(item => return { balanceARS : item.balanceARS, balanceUSD: item.balanceUSD})
// filteredArray = [{ balanceARS : "...", balanceUSD: "..."}]
this.lastCashMovs = filteredArray[0];
console.log(balanceARS, balanceUSD)
}, error => {
console.log(error)
})
}

Related

How to asynchronously manipulate a deeply nested object by referennce

I am working on a gridsome project, where I am manipulating a schema and rendering pages based on that. So, I am passing a reference of schema to a function, which function will manipulate a deeply nested object like,
{
URL: "some.url"
paramas: {"some params}
}
to
{
URL: "some.url"
params: {"some params}
props:{
data:[] || {}
}
}
this manipulation will happen based on the URL and param, so I need to use forEach loop but unfortunately, forEach loop is not asynchronous.
Here I am out of ideas what I need to do if I want to manipulate all those objects (more than 100) from other module and it has to be asynchronous.
a demo schema:
{
"name": "home",
"path": "/",
"header": "top_header",
"footer": "bottom_footer",
"rows": [
{
"row_class": "bg-white",
"columns_class": "cols-66-33 cols-separated cols--height-equal",
"column_1": [
{
"name": "Coral/HomeNews",
"props": {
"tag": "main"
}
}
],
}
]
}
edit:
So I am calling a function from other module like
await dataExtender(_schema);
which contains a function(currently I am developing it, and not complete) which is
const dataExtender = async _schema => {
// Define forEach function
console.log(chalk.green("Data Extending starts from module level"));
await Promise.all(
_schema.pages.forEach(async page => {
page.rows.forEach(row => {
row.column_1.forEach(async column => {
if (column.url !== undefined) {
await axios
.post(column.url, column.param || {})
.then(data => {
console.log(chalk.green("Extending"));
if (Array.isArray(data.data)) {
column.props.data = [...data.data];
} else {
column.props.data = { ...data.data };
}
})
.catch(err => {
console.log(err);
});
}
});
if (row.column_2 !== undefined) {
row.column_2.forEach(async column => {
if (column.url !== undefined) {
await axios
.post(column.url, column.param || {})
.then(data => {
column.props.data = data.data;
})
.catch(err => {
console.log(err);
});
}
});
}
});
}),
);
console.log(chalk.green("Data Extending finishes from module level"));
return _schema;
};
While forEach itself is not async-aware, that doesn't stop you from being able to push the asynchronous modification promises onto a list and awaiting for all of them at the end.
import axios from "axios";
async function processColumn(column) {
const data = await axios.post(column.url, column.param || {});
console.log(chalk.green("Extending"));
if (Array.isArray(data.data)) {
column.props.data = [...data.data];
} else {
column.props.data = { ...data.data };
}
}
async function processColumn2(column) {
const data = await axios.post(column.url, column.param || {});
column.props.data = data.data;
}
const dataExtender = async (_schema) => {
console.log(chalk.green("Data Extending starts from module level"));
const promises = [];
_schema.pages.forEach((page) => {
page.rows.forEach((row) => {
row.column_1.forEach((column) => {
if (column.url !== undefined) {
promises.push(processColumn(column));
}
});
if (row.column_2 !== undefined) {
row.column_2.forEach((column) => {
if (column.url !== undefined) {
promises.push(processColumn2(column));
}
});
}
});
});
await Promise.all(promises);
console.log(chalk.green("Data Extending finishes from module level"));
return _schema;
};

How put Firebase object to state in react?

I'm learning react and I'm having difficulty putting data from Firebase into the application state. I use Rebase but I am open to any solution!
still have an error similar to this one :
Thank you for your help !
Here is the code :
class App extends Component {
state = {
user:'',
vampires: {}
}
componentDidMount() {
if(this.state.user === ''){
firebase.auth().onAuthStateChanged(user => {
if(user){
this.handleUserLogin({ user })
this.setVampires({ user })
} else {
console.log('error')
}
})
}
}
setVampires = async (authData) => {
console.log(this.state.user)
await base.fetch(`/${authData.user.uid}/vampires`, { context: this })
.then(data => {
console.log(data)
let vampires = this.state.vampires;
vampires = {..._.cloneDeep(data)};
this.setState({vampires: {vampires}})
})
}
handleUserLogin = async authData => {
this.setState({user: authData.user.uid})
}
Your Firebase data is returned as an Object, with properties VampM5-..... React expects that you pass any repeated data as an array, not as an object.
So you'll need to convert the data from Firebase to an array, for example with:
await base.fetch(`/${authData.user.uid}/vampires`, { context: this })
.then(data => {
vampires = [];
data.forEach((child) => {
vampires.push({ ...child.val(), ".key": child.key });
})
this.setState({ vampires: vampires })
})

Angular & Firebase get data in observable in value changes

Problem with got data correctly execute function many one times, these function is execute in ngOnInit one time with abstraction but i dont know ocurrs these problem in a server, i thing in snapshotChanges but i don't know.
thx for help
https://i.stack.imgur.com/EinQg.png
return <Observable<Products[]>> t.db.collection(PATHS_FIRESTORE.products).snapshotChanges()
.pipe(
map(actions => {
let arr = actions.map((res) => {
let doc: any = <any>res.payload.doc.data()
let obj: any = {}
if (!isNullOrUndefined(cart)) {
for (const prod in cart) {
if (cart.hasOwnProperty(prod)) {
const element = cart[prod];
if (doc.uid === prod) {
obj[doc.uid] = {
name_product: doc.name_product,
path_img: doc.path_img,
price: doc.price,
quantity: doc.quantity + element.total,
uid: doc.uid,
uid_local: doc.uid_local
}
} else {
t.db.collection(PATHS_FIRESTORE.products).doc(prod).ref.get().then( res => {
const data = res.data()
return obj[res.id] = {
name_product: data.name_product,
path_img: data.path_img,
price: data.price,
quantity: element.total,
uid: doc.uid,
uid_local: doc.uid_local
}
})
}
}
console.log(obj)
}
return obj
}else {
obj = {
...doc
}
return obj
}
})
.filter((b: any) => {
return b.uid_local === uid_local
})
.filter((b: any) => {
return b.quantity > 0
})
.filter((b: any) => {
return !b.status
})
console.log(arr)
return arr
})
)

Collections within documents in firebase and angular 7

I have the following code to obtain two observables in one and be able to manipulate them.
public products: any;
ngOnInit() {
this.products = this.productService.products().snapshotChanges().map(productSnaps => {
return productSnaps.map(product => {
const productData = product.payload.doc.data();
const productId = product.payload.doc.id;
return this.productService.getProductImages(productId).snapshotChanges().map(uploadSnap => {
let number = 0;
return uploadSnap.map(upload => {
if(number == 0) {
number++;
return upload.payload.doc.data();
}
})
})
.map(uploads => {
return {productId, ...productData, uploads: uploads};
})
})
})
.flatMap(products => Observable.combineLatest(products));
}
The services of products() and getProductImages() are the following:
type productsCollection = AngularFirestoreCollection<Product[]>;
products(): productsCollection {
return this.afs.collection<Product[]>('products');
}
getProductImages(productId: string) {
return this.afs.doc<Product>(`products/${productId}`).collection('uploads');
}
I have a base in firebase with the following structure:
my estructur of firebase
But it does not compile me with rxjs 6, I tried to do it like this:
ngOnInit() {
this.products = this.productService.products().snapshotChanges().pipe(map(productSnaps => {
return productSnaps.map(product => {
const productData = product.payload.doc.data();
const productId = product.payload.doc.id;
return this.productService.getProductImages(productId).snapshotChanges().pipe(map(uploadSnap => {
let number = 0;
return uploadSnap.map(upload => {
if (number === 0) {
number++;
return upload.payload.doc.data();
}
});
}),
map(uploads => {
return {productId, ...productData, uploads: uploads};
})
);
});
})
).flatMap(products => Observable.combineLatest(products));
}
But mark the flatMap and the combineLatest error
What at the end of accounts I need is that in the variable products both the documents of the collection "products" are stored as well as the collection that is inside each document and that contains the images of these.
and be able to use them like this:
<img height="250" *ngIf="product.uploads[0]" mat-card-image [src]="product.uploads[0].url" />
<mat-card-title>{{ product.name }}</mat-card-title>
tanks for you help!.

setState is not merging the values

I use the following code in react in order to update state. state should finally looks like this:
this.state.output = {
'abc':{
value: 10
},
'cde':{
value: 20
}
// new values are added and old kept (if not overwritten)
}
My handler:
handleChange = (data) => {
this.setState(prevState => {
return {
output: {
[data.id]: { ...data },
},
}
})
}
When the data is passed in to handleChage with a new data.id, output does not add the new key, instead completely replace all its content
this.state.output = {
'new':{
value: 2
},
}
I need instead keep the previous key also. What is wrong in my code?
Because you forgot to add the other property and their values, update the object like this:
handleChange = (data) => {
this.setState(prevState => {
return {
output: {
...prevState.output, // notice this
[data.id]: { ...data },
},
}
})
}
Or simply:
handleChange = (data) => {
this.setState(prevState => ({
output: {
...prevState.output,
[data.id]: { ...data },
},
})
)}
object spread syntax is recent spec. Here is the documentation for it: using-object-spread-operator
Below code uses Object.assign method instead :
handleChange = (data) => {
this.setState(prevState => ({
output: Object.assign({}, prevState, {
[data.id]: data
})
})
)}

Categories