How to show the data category wise in MERN? - reactjs

I am currently developing a small web app using MERN. Here I have developed the backend part and frontend part of it. I want to get the response data category-wise. For example, in my database there are details of assets(Laptops, mobiles etc) with attributes like assetName and assetCategory. There's a functionality to search those assets category-wise. In the frontend, I have used a search bar and user can type the category of asset which is wanted to see. Then backend server gives the response of that. I have developed routes and controllers for the backend part and I will show the controller here.
//find assets by category
exports.assetsByCategory = async(req,res) => {
const CATEGORY = req.body.assetCategory;
const asset = await Asset.find({"assetCategory" :{$regex: new RegExp([CATEGORY?.toLowerCase()], "i") }})
.then((assets)=>{
res.json(assets)
}).catch((err)=>{
console.log(err);
res.status(500).send({message:"No assets like that category!",error:err.message})
})
}
The code for this function which is in the frontend part will be shown here.
function searchCategoryBar(e)
{
e.preventDefault();
const searchedCategory = {assetCategory}
console.log(searchedCategory)
axios.get("http://localhost:8070/assets/category",searchedCategory).then((asset)=>{
setAssets(asset.data);
console.log(asset.data);
}).catch((err)=>{
alert(err.message);
})
}
So that, when I type "lap" on the search bar and then the response must be shown the asset list of laptop category. But in here, response shows all the assets lists without category-wise.
Please give me some help to solve this issue, Thank you!

Related

React js backend how to get the price_data info from stripe.checkout.session.line_items and push the data into firestore

I am trying to push the stripe checkout line_items price data to firestore by creating a webhook functions using react node js as the below code shown.
exports.stripeWebhook=functions.https.onRequest(async (req, res)=>{
const stripe = require("stripe")(functions.config().stripe.token);
let event;
try {
const whSec=functions.config().stripe.payments_webhook_secret;
event =stripe.webhooks.constructEvent(
req.rawBody,
req.headers["stripe-signature"],
whSec,
);
} catch (err) {
console.error("Webhook signature verification failed.");
return res.sendStatus(400);
}
const dataObject=event.data.object;
const session = await stripe.checkout.sessions.retrieve(dataObject.id, {
expand: ['line_items']
});
await admin.firestore().collection("customer").doc(String(dataObject.customer_email)).collection("order").doc().set({
checkoutSessionId:dataObject.id,
paymentStatus: dataObject.payment_status,
shppingInfo:dataObject.shipping,
amountTotal:dataObject.amount_total/100,
customerId:dataObject.customer,
CustomerEmail:dataObject.customer_email,
orderItems:session.line_items.price_data,
});
return res.sendStatus(200);
});
The function works fine except orderItems:session.line_items.price_data, it shows an error as an undefined firestore value. if I change to orderItems:session.line_items, it has no error, but the line_items info shown in firestore (screen shot below is not what I want, I just want the line_items.price_data which include just item title, price and images.
My question is how to get each item price_data from line_items?
You could try using the listLineItems method instead, and expand the product object inside data.price.product (according to the guide for expanding nested objects in lists).
const lineItems = await stripe.checkout.sessions.listLineItems(id, {expand: ['data.price.product']})
As you are currently retrieving the Session object with the expanded line_items data, this data won't include the product's name, images, description, etc. It looks like the problem is caused by these API calls, as opposed to something in your Firebase function or Firestore.
We can see that the product data from list_items.data.price.product is shown as expandable, which confirms it needs to be expanded. It also seems that there is no price_data field (but instead only price) nor product_data (but instead product) within the responses. These specific fields are apparently available only when creating Sessions.
You would end up with something like:
await admin.firestore().collection("customer").doc(String(dataObject.customer_email)).collection("order").doc().set({
//...
orderItems: lineItems.data[0].price //includes product details from nested expand
});
Since line items data is an array containing each item, you would need to build the array to save in Firestore as your use case requires. Let me know if this was helpful.

Trying to read products from back4app onto a web page with carditem view React & Back4APP

I am currently trying to produce a forum page where users can post products onto a forum page for other users to see. I have it writing to the db and saving the products - however i now want to read back from the products and produce each product for other users to see. Cant seem to find much guidance on it.
enter image description here
Image is current code of the readProducts function that I have created. Thanks
(async () => {
// Creates a new Query object to help us fetch MyCustomClass objects
const query = new Parse.Query('MyCustomClass');
try {
// Executes the query, which returns an array of MyCustomClass
const results = await query.find();
console.log(`ParseObjects found: ${JSON.stringify(results)}`);
} catch (error) {
console.log(`Error: ${JSON.stringify(error)}`);
}
})();

Firebase realtime database - filtering query not on client side Web/React

Quite new to Firebase and I'm facing some issue on the logic on querying/filtering the needed requests.
I have my users stored in the /users and they have a list of projects such as :
users : {
userA : {
projects: {
projectId1: true,
projectId2: true
},
...
}
...
}
And obviously I have the projects as such:
projects: {
projectId1: {
name: "bla"
}
...
}
I want for a user to query all the projects that are in his projects list based on their Ids.
Right now I only succeed to query every single projects of the database and their filter on the client side but obviously this has some serious security implication and loading time as well as I don't want anyone to query all the projects and get them. I can add security rules but then I have access to nothing as I can't query /projects/ anymore but need to be specific.
I'm using https://github.com/CSFrequency/react-firebase-hooks/tree/master/database
and getting the data as such:
const [projects, loading, error] = useListVals(firebase.db.ref("projects"), {
keyField: "uid",
});
And so would like to be able to add an array of projected in this request like where({ id is included in [projectsId]})
You'll need to load each individual project for the user separately, pretty much like a client-side join operation. This is not nearly as slow as you may think, as Firebase pipelines the operations over a single connection.
I don't see anything built into the library you use for such client-side joins, but in regular JavaScript it's something like this:
let userRef = firebase.database().ref('users').child(firebase.auth().currentUser.uid);
userRef.once('value').then((projectKeys) => {
let promises = [];
projectSnapshot.forEach((projectKey) => {
let key = projectKey.key;
let projectRef = firebase.database().ref('projects').child(key);
promises.push(projectRef.once('value');
});
Promise.all(promises).then((snapshots) => {
console.log(snapshots.map(snapshot => snapshot.val()));
});
});

How to create and update a text file using React.js?

I am trying to save a variable's data into a text file and update the file every time the variable changes. I found solutions in Node.js and vanilla JavaScript but I cannot find a particular solution in React.js.
Actually I am trying to store Facebook Long Live Access Token in to a text file and would like to use it in the future and when I try importing 'fs' and implementing createFile and appendFile methods I get an error saying Method doesn't exist.
Please help me out. Here is the code below
window.FB.getLoginStatus((resp) => {
if (resp.status === 'connected') {
const accessToken = resp.authResponse.accessToken;
try {
axios.get(`https://graph.facebook.com/oauth/access_token?client_id=CLIENT_id&client_secret=CLIENT_SECRET&grant_type=fb_exchange_token&fb_exchange_token=${accessToken}`)
.then((response) => {
console.log("Long Live Access Token " + response.data.access_token + " expires in " + response.data.expires_in);
let longLiveAccessToken = response.data.access_token;
let expiresIn = response.data.expires_in;
})
.catch((error) => {
console.log(error);
});
}
catch (e) {
console.log(e.description);
}
}
});
React is a frontend library. It's supposed to be executed in the browser, which for security reasons does not have access to the file system. You can make React render in the server, but the example code you're showing is clearly frontend code, it uses the window object. It doesn't even include anything React-related at first sight: it mainly consists of an Ajax call to Facebook made via Axios library.
So your remaining options are basically these:
Create a text file and let the user download it.
Save the file content in local storage for later access from the same browser.
Save the contents in online storage (which could also be localhost).
Can you precise if any of these methods would fit your needs, so I can explain it further with sample code if needed?

React / Rails API Image Uploading

I've built a React frontend along with a Rails API only backend. I want to allow the user to create a task and enter a title, description and upload an image.
So I've attempted to use DropZone to get access to the image and then send the image info along with the title and description to my Rails API via a post request using Axios.
I set up Carrierwave on my Rails API in hopes of uploading to an AWS S3 bucket once my Task has been added to the database per the post request.
None of this is working so my question is, should I take care of the image uploading to AWS on the react side and if so, how do I associate that image with the additional information I'm saving to my Rails database (title and description).
Thanks!
First, on React side, there should be no proble with title and description, but for image, you need to encode the image to Base64 string. It is something like this.
getBase64 = (callback) => {
const fileReader = new FileReader();
fileReader.onload = () => {
console.log(fileReader.result);
};
fileReader.readAsDataURL(fileToLoad);
fileReader.onerror = (error) => {
console.log('Error :', error);
};
}
Then, on Axios, send those 3 parameters alltogether with one POST request.
For Rails, you need to set up code that can read the Base64 string. Usually, you can use Paperclip or CarrierWavegem to add image attachment. It will look like this.
property_image = listing.property_images.new(param_image)
if param_image[:file_data]
image_file = Paperclip.io_adapters.for(param_image[:file_data])
image_file.original_filename = param_image[:image_file_name]
image_file.content_type = "image/png"
property_image.image = image_file
end
private
def param_image
params.permit(:image, :image_file_name, :file_data)
end

Resources