Can't fetch data in FaunaDB when using variable in API route - database

I have an API route, and it works:
import { query as q } from 'faunadb';
export default async (req, res) => {
try {
const customer = await guestClient
.query(q.Get(q.Match(q.Index('user_by_username'), "feronimo")))
.catch((err) => console.error('Error: %s', err));
res.status(200).json(customer.data);
console.log(customer.data + 'cd');
console.log(customer + 'c');
} catch (e) {
res.status(500).json({ error: e.message });
}
};
My username is "feronimo" and it comes when I type. However, I have to take this as a variable.
I am sending the variable with useSWR:
const fetcher = (params) => (url) => post(url, params);
const { data: info, error } = useSWR(
`/api/profilepages`,
fetcher({ key: username }) /* {
dedupingInterval: 1000000
} */
);
It's returning { username: 'feronimof' }.
export default async (req, res) => {
const username = req.body;
const u = username.username;
try {
const customer = await guestClient
.query(q.Get(q.Match(q.Index('user_by_username'), u)))
.catch((err) => console.error('Error: %s', err));
res.status(200).json(customer.data);
console.log(customer.data + 'cd');
console.log(customer + 'c');
} catch (e) {
res.status(500).json({ error: e.message });
}
};
This returns [object Object].

You could use a dynamic API route in that case, e.g., pages/api/profilepages/[username].js. This allows you to pass a variable when making a request against it.
// In your component code that makes the request
const { data: info, error } = useSWR(
`/api/profilepages/${username}`,
fetcher()
);
// pages/api/profilepages/[username].js
export default async (req, res) => {
const u = req.query.username; // This would return the username you sent
// Your API logic here
};

Related

Mobx action method after an axios delete call doesn't run at all

Everything works fine up until the TaskStore.fetchTasks() call. The data is deleted from the database, but if I console log anything past the axios delete call, it doesn't even show. This is causing my component to not rerender because the observable in the store is not being updated with the new data without the deleted value.
DeleteTask.tsx:
export default function DeleteTask(value?: any) {
const deleteTask = async (e: any) => {
e.preventDefault();
try {
let data = { task: value.value.task };
await axios.delete(`http://localhost:5000/test`, {
data,
});
await TaskStore.fetchTasks();
} catch (error: Error | any) {
console.log(error);
}
};
fetchTasks:
#action fetchTasks = async () => {
try {
const response: any = await axios.get('http://localhost:5000/test');
runInAction(() => {
this.tasks = [];
console.log('before pushing' + this.tasks);
this.tasks.push(...response.data.recordset);
console.log('after pushing' + this.tasks);
});
} catch (error) {
console.error(error);
}
};
in general you have to create type for what data comes from api.
then create an empty object array from from type then check the solved function do that and your problem will solved.
//Your Code
#action fetchTasks = async () => { try {
const response: any = await axios.get('http://localhost:5000/test');
runInAction(() => {
this.tasks = [];
console.log('before pushing' + this.tasks);
this.tasks.push(...response.data.recordset);
console.log('after pushing' + this.tasks);
});
} catch (error) {
console.error(error);
}
};
Your Component
// Here you just call your delete function from task store and that's all
export default function DeleteTask(value?: any) {
const deleteTask = async (e: any) => {
e.preventDefault();
try {
TaskStore.deleteTask(data);
} catch (error: Error | any) {
console.log(error);
}
};
the Code that is Solved
first you have to create a type for what data comes from api
// create Type to get data from api and store in it
interface Tasks {
// here any fields you get from api set here
id: number;
name: string;
// etc
}
Create empty array object from type
TasksList: Tasks[] = []; // for task List
your Fixed function
// added New Delete Function
#action deleteTask = async (data: any) => {
try {
await axios.delete(`http://localhost:5000/test`, {
data,
});
runInAction(() => {
this.fetchTasks();
});
} catch (error) {
console.log(error);
}
};
Fetch Function
#action fetchTasks = async () => {
try {
// define your type for axios
const response = await axios.get<Tasks[]>('http://localhost:5000/test');
this.TasksList = []; // Bring it out from Run in action
runInAction(() => {
// add Data with response in below line
this.TasksList = response.data; //just sample assign response to Task List
});
} catch (error) {
console.error(error);
}
};

How to make a PATCH request in ReactJS ? (with Nestjs)

nestjs controller.ts
#Patch(':id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
#Body('shippingAddr') addrShipping: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling, addrShipping);
return null;
}
nestjs service.ts
async updateProduct(
addressId: string,
addrBilling: boolean,
addrShipping: boolean,
) {
const updatedProduct = await this.findAddress(addressId);
if (addrBilling) {
updatedProduct.billingAddr = addrBilling;
}
if (addrShipping) {
updatedProduct.shippingAddr = addrShipping;
}
updatedProduct.save();
}
there is no problem here. I can patch in localhost:8000/address/addressid in postman and change billingAddr to true or false.the backend is working properly.
how can i call react with axios?
page.js
const ChangeBillingAddress = async (param,param2) => {
try {
await authService.setBilling(param,param2).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
return....
<Button size='sm' variant={data.billingAddr === true ? ("outline-secondary") : ("info")} onClick={() => ChangeBillingAddress (data._id,data.billingAddr)}>
auth.service.js
const setBilling = async (param,param2) => {
let adressid = `${param}`;
const url = `http://localhost:8001/address/`+ adressid ;
return axios.patch(url,param, param2).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}
I have to make sure the parameters are the billlingddress field and change it to true.
I can't make any changes when react button click
Since patch method is working fine in postman, and server is also working fine, here's a tip for frontend debugging
Hard code url id and replace param with hard coded values too:
const setBilling = async (param,param2) => {
// let adressid = `${param}`;
const url = `http://localhost:8001/address/123`; // hard code a addressid
return axios.patch(url,param, param2).then((response) => { // hard code params too
console.log(response); // see console result
if (response.data.token) {
// localStorage.setItem("user", JSON.stringify(response.data));
}
// return response.data;
})
}
now it worked correctly
#Patch('/:id')
async updateProduct(
#Param('id') addrId: string,
#Body('billingAddr') addrBilling: boolean,
) {
await this.addrService.updateProduct(addrId, addrBilling);
return null;
}
const ChangeBillingAddress = async (param) => {
try {
await authService.setBilling(param,true).then(
() => {
window.location.reload();
},
(error) => {
console.log(error);
}
);
}
catch (err) {
console.log(err);
}
}
const setBilling= async (param,param2) => {
let id = `${param}`;
const url = `http://localhost:8001/address/`+ id;
return axios.patch(url,{billingAddr: param2}).then((response) => {
if (response.data.token) {
localStorage.setItem("user", JSON.stringify(response.data));
}
return response.data;
})
}

How to fetch data from MongoDB?

I am trying to use Express + MongoDB building React app.
I was able to post some documents to MongoDB. Currently, I'm trying to figure out how to print fetched data to the screen.
I have these routes:
router.post('/totalbalance', (request, response) => {
const totalBalance = new TotalBalanceModelTemplate({
totalBalance:request.body.totalBalance,
});
totalBalance.save()
.then(data => {
response.json(data);
})
.catch(error => {
response.json(error);
});
});
router.get('/totalbalance', (request, response) => {
TotalBalanceModelTemplate.find(request.body.totalBalance, (error, data) => {
if (error) {
return error
} else {
response.json(data[0])
}
})
});
This is axios request:
useEffect(() => {
const resp = axios.get('http://localhost:4000/app/totalbalance');
console.log(resp);
}, []);
It returns a promise that has a parameter data which equals to object value which is the first value in the array
data: {_
id: "60c48b4ec60919553d92319f",
totalBalance: 5555,
__v: 0
}
and prints it out to the console.
How can I print out to the console the value totalBalance instead of whole promise?
By the way, sometime the array of data is empty (there are no documents in the DB), how should i handle these cases as well?
Thanks!
First of all, Axios GET method does not have any request body. But you are trying to use it in the MongoDB query. - "TotalBalanceModelTemplate.find(request.body.totalBalance, (error, data) => {".
The find query should be object {}. If require pass on conditions to it.
First point, to print only "totalBalance" output. Use, console.log(resp.totalBalance);
Second point, to handle records length, have a if else condition,
if (error) {
return error
} else if (data.length) {
return response.send("No records found")
} else {
response.json(data[0])
}
Try this :
Routes
router.post("/totalbalance", async (req, res) => {
try {
const totalBalance = new TotalBalanceModelTemplate({
totalBalance: req.body.totalBalance,
})
await totalBalance.save();
res.json(totalBalance)
} catch (error) {
res.status(400).json({
message: error.message
})
}
})
router.get("/totalbalance", async (req, res) => {
try {
const totalBalances = await TotalBalanceModelTemplate.find();
res.json(totalBalances)
} catch (error) {
res.status(400).json({
message: error.message
})
}
})
App.js
import React, { useState, useEffect } from 'react';
import axios from 'axios';
export default function App() {
const [data, setData] = useState([]);
const getData = async () => {
try {
const response = await axios.get('http://localhost:4000/app/totalbalance');
await setData(response);
} catch (error) {
console.log(error);
}
};
useEffect(() => {
getData();
}, []);
return (
<div>
{data <= 0 ? (
<div className="empty">
<p>No data!</p>
</div>
) : (
data.map((d) => (
<ul key={d.id}>
<li>{d.totalBalance}</li>
</ul>
))
)}
</div>
);
}

Sending verification email with Firebase and React Native

I am trying to send the validation email upon the account registration, using firebase. The registration is being done successfully but whenever I try to code email verification it gives me an error. Probably because I don't know where to place it. All my firebase methods are on Fire.js, which are the following:
import firebaseKeys from './Config';
import firebase from 'firebase';
require("firebase/firestore");
class Fire {
constructor() {
if (!firebase.apps.length) {
firebase.initializeApp(firebaseKeys);
}
}
addPost = async ({ text, localUri }) => {
const remoteUri = await this.uploadPhotoAsync(localUri, 'photos/${this.uid}/${Date.now()}');
return new Promise((res, rej) => {
this.firestore.collection('posts').add({
text,
uid: this.uid,
timestamp: this.timestamp,
image: remoteUri
})
.then(ref => {
res(ref);
})
.catch(error => {
rej(error);
});
});
}
uploadPhotoAsync = async (uri, filename) => {
return new Promise(async (res, rej) => {
const response = await fetch(uri);
const file = await response.blob();
let upload = firebase
.storage()
.ref(filename)
.put(file);
upload.on(
"state_changed",
snapshot => {},
err => {
rej(err);
},
async () => {
const url = await upload.snapshot.ref.getDownloadURL();
res(url);
}
);
});
}
createUser = async user => {
let remoteUri = null
try {
await firebase.auth().createUserWithEmailAndPassword(user.email, user.password)
//I tried to code it here with user.sendEmailVerification();
let db = this.firestore.collection("users").doc(this.uid)
db.set({
name: user.name,
email: user.email,
avatar: null
})
if (user.avatar) {
remoteUri = await this.uploadPhotoAsync(user.avatar, 'avatars/${this.uid}')
db.set({avatar: remoteUri}, {merge: true});
}
} catch (error) {
alert("Error: ", error);
}
};
get firestore() {
return firebase.firestore();
}
get uid() {
return (firebase.auth().currentUser || {}).uid;
}
get timestamp() {
return Date.now();
}
}
Fire.shared = new Fire();
export default Fire;
The createUserWithEmailAndPassword() method returns a Promise which resolves with a UserCredential AND (as the the doc indicates) "on successful creation of the user account, this user will also be signed in to your application."
So you can easily get the signed in user by using the user property of the UserCredential, and call the sendEmailVerification() method, as follows:
try {
const userCredential = await firebase.auth().createUserWithEmailAndPassword(user.email, user.password);
await userCredential.user.sendEmailVerification();
//In the next line, you should most probably use userCredential.user.uid as the ID of the Firestore document (instead of this.uid)
cont db = this.firestore.collection("users").doc(this.uid);
//...
} catch (...)
Note that you may pass an ActionCodeSettings object to the sendEmailVerification() method, see the doc.

Axios-Redux in React to an Express endpoint-both .then and .catch triggered

I'm using a Redux Form to send a POST call to an Express endpoint. The endpoint is supposed to return the successfully saved object, or an error.
The endpoint successfully saves the posted data and returns the JSON. But Axios in the Redux action picks up both the .then and the .catch triggers-in the following action, it logs the following:
successful response: { …}
failure response: undefined
What am I doing wrong?
My Axios action:
export function addPlot(props) {
const user = JSON.parse(localStorage.getItem('user'));
return function(dispatch) {
axios
.post(
`${ROOT_URL}/plots`,
{
props
},
{ headers: { authorization: user.token } }
)
.then(response => {
console.log('successful response: ', response.data);
const plotModal = document.getElementById('plotModal');
plotModal.modal('dispose');
dispatch({ type: PLOT_ADDED, payload: response.data });
dispatch({ type: ADDING_PLOT, payload: false });
dispatch({
type: NEW_PLOT_GEOJSON,
payload: ''
});
})
.catch(response => {
console.log('failure response: ', response.data);
dispatch(authError(PLOT_ADD_FAILURE, 'Failed to add plot'));
});
}
My endpoint:
exports.newPlot = async (req, res, next) => {
console.log(JSON.stringify(req.body.props));
let company;
if (req.user.companyCode !== 'Trellis') {
company = req.user.companyCode;
} else {
company = req.body.props.company;
}
const {
name,
feature,
growerPhone,
plotCode,
rootStock,
region,
variety,
grower,
planted
} = req.body.props;
const plot = new Plot({
name,
grower,
variety,
planted,
region,
rootStock,
plotCode,
growerPhone,
feature,
company
});
try {
const newPlot = await plot.save();
res.json(newPlot);
} catch (e) {
console.log("couldn't save new plot", JSON.stringify(e));
return res.status(422).send({ error: { message: e, resend: true } });
}
};
You could use redux-thunk middleware to manage async actions.
The problem I see is that you are not dispatching the axios action, you must call dispatch(this.props.addPlot(props))in order to do something in the redux store.

Resources