How to pass data of an object to HTML file - javascript

I have few posts in my app, and I want that when user selects one of them, he to be redirected to a Post.html page which contains all details about that specific product. I have two methods, createPost() for creating a product dynamically where I pass postId in order to keep track of that product, and getPosts() to get the posts from database. I am saving all posts in an array in localStorage to have data about the selected product in Post.html. I added an addEventListener() but not sure how to use it. The problem is that I am stuck how to get the information of that post and pass it to Post.html.
function getPosts() {
firebase
.firestore()
.collection("products")
.get().then(snapshot => {
let products = [];
snapshot.docs.forEach((doc) => {
products.push(doc.data());
createPost(
doc.data().title,
doc.data().description,
doc.data().price,
doc.data().postId
);
});
localStorage.setItem(`${products}`, JSON.stringify(products));
})
.catch((err) => {
console.log(err);
});
}
function createPost(title, description, price, postId) {
let div = document.createElement("div");
div.setAttribute("class", "product-home-show");
......
div.appendChild(divSellerRoundImage);
div.appendChild(divSellerName);
div.appendChild(divProductDescription);
div.appendChild(divProductName);
div.appendChild(divProductPrice);
productsCollection.appendChild(div);
div.addEventListener("click", function () {
// console.log(localStorage.getItem());
// window.location.href = "post.html";
});
}

You can get data from localStorage on another page. Use localStorage.getItem(keyName); Also keep in mind the first argument to setItem is the key name. I'd recommend changing your code to: localStorage.setItem("products", JSON.stringify(products));. Then you'll be able to retrieve your product list with they key "products."
Also, if you're saving an object, you'll need to parse it since it will be saved as a string. You can use JSON.parse
For example:
var retrievedData = localStorage.getItem("products");
var productListObject = JSON.parse(retrievedData);
You can save the selected post ID in another value in local storage, or a cookie. Lastly, you may want to consider using sessionStorage if you don't need the data stored after the session is over. See this link for more information

Related

Mongoose Update document

I am using Node.js and mongoose Module, I am looking for a way to count how many documents a user has and then if they have more then 0 documents it would edit their existing document and add the input so at the end it would have the previous text + the text that the user sent, so far this is how much I gotten.
const List = require('../Models/list.js')
List.countDocuments({}, function(err, count) {
if(count>0){
//edit document
}
else if(count=0){
const input = List.create({
User: User.name,
Songlist: args[0],
})
}
})
console.log('done')
here is how I think the code would look like
List.update(User.name) => update Songlist into List.Songlist + '|' + args[0]
I have never seen an update method like that. I am a nodejs developer. well, maybe there's a way like that.
Here's how I do to update a document
await Product.findByIdAndUpdate(id, //here where I have written "id" you have to write the id of the document you want to update.
{ //here in this object you have to put the variables of updated values
title: title,
description:description,
product_id:product_id,
category,
price,
});
there is also another method
await Product.findOneAndUpdate(name: 'asim', //let's suppose
{ //updated values
title:title,product: product
})
you can also read the documentation here https://mongoosejs.com/docs/tutorials/findoneandupdate.html

Retrieving data on firebase having child key uid (javascript)

I am struggling how to retrieve data from firebase having a child key, such as uid.
here is the structure of my firebase.
Currently I am making an admin panel which can read the order placed by each user and render it through flatlist in react native, but it seems that I can't access their order because every time the user places an order it is stored on their unique User.id
I don't know how to make a reference to the User.id child like firebase.database().ref(orders/${AllUserId}/products)
You can use forEach loop to fetch ids and can get values as so
firebase.database().ref('order').on('value', (snapshot) => {
snapshot.forEach((child) => {
uid = child.key; // gives uid1
child.forEach((snap) =>{
var id = snap.key; // first iteration gives uid2
firebase.database().ref('order/'+uid+'/'+id).on('value', (snapchild) => {
snapchild.forEach((snapshotchild) =>{
console.log(snapshotchild.val());
});
});
});
});
});
This could be more insightful.

Calling then function after fetching data from firebase in ionic 3

I want fetch data from firebase after that I want to execute another function. Second function have to wait until first one is complete .
this.oAngularFireDatabase.database.ref('Users').orderByKey()
.on('value', snapshot => {
if (snapshot.hasChildren()) {
snapshot.forEach(innerSnap => {
if (innerSnap.hasChild(user.uid)) {
//User role key
this.loggedInUserUserRoleKey = innerSnap.key;
//User id
this.loggedInUserId = user.uid;
//User name
this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();
if (innerSnap.child(user.uid).hasChild("user_image")) {
//User Image
this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
}
return false;
}
})
}
})
I can't call then function after on it gives me an error.
In my above code, I want call another function after all data are fetch from firebase.
The Firebase on() method can fire multiple times: once when it initially loads the data, and again whenever the data changes. Since a promise (the thing you call then() on) can only resolve once, on() can't return a promise.
There are two options here:
You want to only load the data once.
If this is the case, you should use Firebase's once() method, which does return a promise.
this.oAngularFireDatabase.database.ref('Users').orderByKey()
.once('value').then(snapshot => {
if (snapshot.hasChildren()) {
snapshot.forEach(innerSnap => {
if (innerSnap.hasChild(user.uid)) {
//User role key
this.loggedInUserUserRoleKey = innerSnap.key;
//User id
this.loggedInUserId = user.uid;
//User name
this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();
if (innerSnap.child(user.uid).hasChild("user_image")) {
//User Image
this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
}
return false;
}
})
}
}).then(value => {
// TODO: perform subsequent action on boolean value
})
You want to listen for changes on the data too.
If this is the case, you should put the subsequent action you want to take into the on() callback:
this.oAngularFireDatabase.database.ref('Users').orderByKey()
.on('value', snapshot => {
if (snapshot.hasChildren()) {
snapshot.forEach(innerSnap => {
if (innerSnap.hasChild(user.uid)) {
//User role key
this.loggedInUserUserRoleKey = innerSnap.key;
//User id
this.loggedInUserId = user.uid;
//User name
this.loggedInUserName = innerSnap.child(user.uid).child("user_name").val();
if (innerSnap.child(user.uid).hasChild("user_image")) {
//User Image
this.loggedInUserImage = innerSnap.child(user.uid).child("user_image").val();
}
}
})
// TODO: perform subsequent action on data
}
})
Note that both of these operations look pretty expensive for what they're trying to accomplish: scanning a JSON tree for a specific value is an anti-pattern in Firebase, and typically means you should modify/augment your JSON to allow a direct lookup or query.
For example, I suspect you now have a structure like /Users/$randomkey/$uid: { ..user data... }. For better performance, consider storing the user data directly under their UID: /Users/$uid: { ..user data... }. This removes the need for a query, and allows you to directly load the data for a user from this.oAngularFireDatabase.database.ref('Users').child(user.uid).

React JS Local Storage update on view change

How can I update certain properties of a local storage item or object as new data is inputted throughout the user journey and not lose what was previously entered or if the user decides to update?
My journey of 5 containers consisting of asking the user to input the following:
Name: string
Avatar: integer
Favourite Genres: multiple strings
On the first view I have created the local storage object / item that sets the name within the handleSubmit function.
handleSubmit(event) {
event.preventDefault();
//Profile object
let profile = { 'name': this.state.name, 'avatar': null, 'genres': '' };
// Put the object into storage
localStorage.setItem('profile', JSON.stringify(profile));
// Retrieve the object from storage
var retrievedObject = localStorage.getItem('profile');
//Log object
console.log('retrievedObject: ', JSON.parse(retrievedObject));
//On form submission update view
this.props.history.push('/profile/hello');
}
On my second view I want to update only the avatar property and maintain what the user had inputted in the previous view.
I'm doing this within the handleSelect function like so:
handleSelect(i) {
let selectedAvatarId;
let avatars = this.state.avatars;
avatars = avatars.map((val, index) => {
val.isActive = index === i ? true : false;
return val;
});
this.setState({
selectedAvatarId: selectedAvatarId
})
//Profile object
let profile = { 'avatar': i };
//Update local storage with selected avatar
localStorage.setItem('profile', JSON.stringify(profile));
}
You will need to read the existing value from localStorage, parse it as JSON and then manipulate the data, and write it back. There are numerous libraries out there for easily working with localStorage, but something along the lines of this should work as a generic function:
function updateProfile = (updatedData) => {
const profile = JSON.parse(localStorage.getItem('profile'));
Object.keys(updatedData).forEach((key) => {
profile[key] = updatedData[key];
});
localStorage.setItem('profile', JSON.stringify(profile));
}
If you use object spread, it could look a lot cleaner too:
function updateProfile = (updatedData) => {
const profile = {
...JSON.parse(localStorage.getItem('profile')),
...updatedData
};
localStorage.setItem('profile', JSON.stringify(profile));
}
There should probably be some safety checks in the above code, but hopefully gives you an idea for a starting point.
The only option as far as I know is to get it as a Json, amend accordingly and then save it is again.

Set an property to object after query.exec()

I am using node express. I am trying to populate a field which is populated from another field. But I was having problem so I tried to get the value from another query and then set it to the object I was sending.
api.get('/:id', authenticate, (req, res) => {
let query = MobileTranscation.findById(req.params.id)
.populate('sender')
.populate('created_by');
query.exec((err, datas) => {
if(datas.sender && datas.sender.parent) {
User.findById(datas.sender.parent, (err, user) => {
datas['parentName'] = user.username;
console.log(datas);
res.json(datas);
});
} else {
res.json(datas);
}
});
});
Here, I want to get username from MobileTranscation.sender in which sender has a parent property which has the username property. I was trying to populate sender and then take the parent id and search User with that and get the username. Problem I am facing is that if I log datas.parentName I can see I got the username, but when I am sending datas, there is no parentName property. What I am doing wrong here?
And is it possible to populate a property and then populate one of that populated property?
Whenever you do findById mongoose actually sends some kind of immutable object in return. So you cannot add an extra key to the object. You actually can use the .lean function. Like query.lean().exec((err, data) => { /** Function body* */ }). Now you can add extra keys you want.

Categories