I want to know how to got COUNT from SQL in reactjs - javascript

my request is good but i want to know how can i use my response in React.
SQL request :
```
exports.countAllComments = async (req, res) => {
const pId = req.params.id;
db.query(
"SELECT COUNT(*) FROM comments WHERE post_id = ?",
[pId],
(err, count) => {
if (err) {
res.status(500).json({ err });
console.log(err);
} else {
console.log(count)
res.status(200).json(count);
}
}
);
};
```
Front for fetch count:
```
const [countData, setCountData] = useState(0);
useEffect(() => {
const fetchCount = async () => {
try {
const fetchData = await Axios.get(
`http://localhost:3001/api/post/comment-count/${post.id}`,
{
headers: { Authorization: `Bearer ${test1.token}` },
}
);
setCountData(fetchData.data[0]);
} catch (err) {}
};
fetchCount();
}, [post.id, test1.token]);
console.log(countData);
```
console log return : "{COUNT(*): 4}" how can i get (4)

given your trivial example, the trivial solution would be something like -
fetchData.data[0]['COUNT(*)']
however, you should really have a think about the contract on the API, and enforce a certain return type from your API, and not just simply return the response from the SQL query. i.e. your API could possibly return an object like -
{ count: x }
where its up to your API to transform the result from the SQL query in a way that satisfies the contract, that way your React client is disconnected from your database layer and only cares about your API contract.
That way your client side becomes something like -
fetchData.data.count
which wouldn't break if the query where to be updated in some way etc.

Related

React: TypeError Cannot read properties of undefined (reading '0')

I am working on a React App, and i'm trying to get some data using an axios GET request from my node backend.
the Api Endpoint i'm currently using that regard this problem is the following:
// NodeJS Backend
app.get('/v1/companys/user/:user_uuid', verify, (req, res) => { // GET - Company by User UUID
const selectQuery = 'SELECT * FROM companys WHERE uuid = (SELECT company_uuid FROM users WHERE uuid = ?)';
connection.query(selectQuery, [req.params.user_uuid], (err, results) => {
if(err) {
res.send(err)
} else if (results.length === 0) {
res.json({status: 404, message: 'Company not found'})
} else {
res.json({data: results})
}
});
});
This is my Front End:
// ReactJS FrontEnd
const companyLogo = userCompany ? userCompany.logo_url : null;
console.log(userCompany);
useEffect(() => {
const getUserCompany = async () => {
try {
await axios.get(process.env.REACT_APP_API_URL + 'companys/user/' + userUuid).then((response) => {
console.log("response "+ response);
let res = response.data.data[0];
console.log(res);
setUserCompany(res);
});
} catch (error) {
console.log(error);
}
};
getUserCompany();
}, [userUuid]);
There app works fine, but on the console the following error appear:
The object below the error is in fact the thing that i need (companyLogo)
I was wondering if someone know what am I doing wrong on my frontend to fix the TypeError.
Thanks for the help!
If you use optional chaining (?.) to catch possible null/undefined values, you'll most likely fix the issue.
So like this: let res = response.data.data?.[0];

Node.js getting Uncaught error: invalid input syntax for type integer: "NaN"

I am very new to JS and I'm trying to create an API using node.js however I'm getting the error:
Uncaught error: invalid input syntax for type integer: "NaN"
The requests are fine when I do a GET and POST request but I'm having trouble with the PUT and DELETE. I get the same error with both requests. Here is my code:
const getProfiles = (request, response) => {
pool.query('SELECT * FROM profiles', (error, results) => {
if (error) {
throw error
}
response.status(200).json(results.rows)
})
}
const addProfiles = (request, response) => {
const {name, bio} = request.body
pool.query(
'INSERT INTO profiles (name, bio) VALUES ($1, $2) RETURNING id',
[name, bio],
(error) => {
if (error) {
throw error
}
response.status(201).json({status: 'success', message: 'Profile added.'})
})
}
const updateProfiles = (request, response) => {
const id = parseInt(request.params.id)
const {name, bio} = request.body
pool.query(
'UPDATE profiles SET name = $1, bio = $2 WHERE id = $3 RETURNING id',
[name, bio, id],
(error) => {
if (error) {
throw error
}
response.status(202).json({status: 'success', message: 'Profile updated with ID: ${id}'})
})
}
const deleteProfiles = (request, response) => {
const id = parseInt(request.params.id)
pool.query(
'DELETE FROM profiles WHERE id = $1', [id],
(error, results) => {
if (error) {
throw error
}
response.status(203).send(`Profile deleted with ID: ${id}`)
})
}
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
// Start server
app.listen(process.env.PORT || 3002, () => {
console.log(`Server listening`)
})
I am very much new to this and if you spot where I went wrong I would very much appreciate and explanation for me to better understand it and never make this mistake again. Thank you.
As far as I can see, req.params.id is undefined, because you are not telling express that route should receive a param.
Change this:
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
To this:
app
.route('/profiles')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
app
.route('/profiles/:id') // :id means we are expecting that param
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)
And when you do the PUT or DELETE request, the endpoint should look like this: /profiles/
The error means you'r providing a "Not a Number" (NaN) where your app expects a number (integer).
It's most probably the id in the updateProfiles or deleteProfiles, because you haven't defined it your route
app
.route('/profiles/:id')
// GET endpoint
.get(getProfiles)
// POST endpoint
.post(addProfiles)
//UPDATE endpoint
.put(updateProfiles)
// DELETE endpoint
.delete(deleteProfiles)

Axios response data is not saved with useState

While trying to fetch data from my express backend and MySQL database, with my react frontend using axios, it fails to set the fetched data using useState
my frontend function looks like this
const searchUser = () => {
Axios.post("http://localhost:3001/searchUser", {
username: username,
}).then((response) => {
if (response.data) {
setResult(response.data);
}
});
};
and my backend function looks like this
const searchUser = (req, res) => {
const keyword = req.body.username;
db.query(
"SELECT id,username FROM users WHERE username like ?",
"%" + keyword + "%",
(err, result) => {
if (err) {
res.json({ message: err });
console.log(err);
} else {
console.log(result);
res.json({ result });
}
}
);
};
I tried many methods while saving the data with the useState hook, I appreciate any help
While using Promises and then instead of async / await make sure to catch the errors if your fetch fails.
Unless you share with us the whole component that contains the searchUser function and how you defined the state i cannot pin point you on the error.
What i suggest you to do is adding a catch to your fetch by doing the following:
const searchUser = () => {
Axios.post("http://localhost:3001/searchUser", {
username: username,
}).then((response) => {
if (response.data) {
setResult(response.data);
}
}).catch((error) => {
console.error(error);
});
};
If any abnormalities has happened in your request the catch will tell you! Don't underestimate it's power.
Another path you can look into is console logging your output in front end searchUser function just before setting it in the state.
I did solve the problem, just by replacing res.json({ result }); to res.json(result); in the last line in my backend function

For fetching a students applied programs

I am trying to fetch all the programs for the current applicant who is logged in and has applied for their bachelor's degree and store the fetched programs object id in an array.
I have tried the following but I'm not sure if it will work at first. Secondly, it will be quite helpful if you let me know what should I do to make it possible. I have shared the code I wrote. It is a MERN stack project and the backend is purely javascript.
Let me know if you can help me with the code below:
// #route GET /api/programs/applied-programs
// #desc Get all applied programs
// #access Private
router.get('/applied-programs', auth, async (req, res) => {
try {
const applicant = await Applicant.findOne({ user: req.user.id })
.select('-password')
.populate('user', ['email']);
let res = [];
const appliedPrograms = applicant.appliedPrograms.forEach(program => {
if (program) {
res = [program.id];
}
return res;
});
res.json(appliedPrograms);
} catch (err) {
console.log(err.message);
return res.status(500).send('Server Error');
}
});
So I just solved it myself. Just remembered that .forEach() function you have to pass an object the condition I was using was putting a check on the programs and I was passing the ids inside the array itself. Which surely is the wrong way to do it. So for now by using the .map() and mapping through the list of object and fetching their ids I just got what I wanted.
This is the proper way of doing so.
// #route GET /api/programs/applied-programs
// #desc Get all applied programs
// #access Private
router.get('/applied-programs/:id', auth, async (req, res) => {
try {
const applicant = await Applicant.findOne({ user: req.user.id })
.select('-password')
.populate('user', ['email']);
let response = [];
const appliedPrograms = applicant.appliedPrograms.map(
program => program.id
// if (program) {
// response = [program.id];
// }
// return response;
// }
);
response = appliedPrograms;
res.json(response);
} catch (err) {
console.log(err.message);
return res.status(500).send('Server Error');
}
});

How to add results from a promise based API call with message.addReply using Recast.ai?

I'm making a bot that searches restaurants based on location. Can anyone help me why this doesnt show up in FB messenger?:
restaurants(result.getMemory('location').raw)
.then(res=>{
message.addReply(res);
message.reply();
});
}
The call to the restaurants function returns the results from a YELP API call (an array of restaurants) but when I add it as a reply to message, nothing happens in FB messenger.
Here is the full code for message.js:
const recastai = require('recastai');
const restaurants = require('./restaurants');
// This function is the core of the bot behaviour
const replyMessage = (message) => {
// Instantiate Recast.AI SDK, just for request service
const request = new recastai.request(process.env.REQUEST_TOKEN,
process.env.LANGUAGE);
// Get text from message received
const text = message.content;
console.log('I receive: ', text);
// Get senderId to catch unique conversation_token
const senderId = message.senderId;
// Call Recast.AI SDK, through /converse route
request.converseText(text, { conversationToken: senderId })
.then(result => {
//Recast takes text analyses that, returns a result object, generates replies adds messages to reply stack and then sends the replies
//Call Yelp API with when the intent is Location. When Yelp returns result we add it to the result.replies array.
//Then we add everything in result.replies to the messaging queue that sends the responses to FB
if (result.action) {
console.log('The conversation action is: ', result.action.slug);
}
// If there is not any message return by Recast.AI for this current conversation
if (!result.replies.length) {
message.addReply({ type: 'text', content: 'I don\'t have the reply to this yet :)' });
} else {
// Add each reply received from API to replies stack
result.replies.forEach(replyContent => message.addReply({ type: 'text', content: replyContent }));
}
// Send all replies
message.reply()
//send initial reply generated by Recast first
.then(() => {
//call restaurant function that returns a list of results from API
//if the action is location and done
if(result.action && result.action.slug === 'location' && result.action.done){
restaurants(result.getMemory('location').raw)
.then(res=>{
console.log(res);
message.addReply(res);
message.reply();
});
}
})
.catch(err => {
console.error('Error while sending message to channel', err);
});
})
.catch(err => {
console.error('Error while sending message to Recast.AI', err);
});
};
module.exports = replyMessage;
And here is my restaurants.js code that is imported into the message.js file for the bot behavior:
const rp = require('request-promise');
// Load configuration
require('./config');
const restaurants = (location) => {
return Promise.all([
yelpCall(location)
]).then(result => {
//result contains the return value from Yelp call
return result;
});
};
const yelpCall = (location) => {
const auth = {
method: 'POST',
url: 'https://api.yelp.com/oauth2/token?grant_type=client_credentials&client_id='+ process.env.YELP_APP_ID +'&client_secret='+process.env.APP_SECRET
};
return rp(auth)
.then(result => {
const tokens = JSON.parse(result);
return tokens;
})
.then(result=>{
const options = {
url: 'https://api.yelp.com/v3/businesses/search?location=' + location + "&term=thai",
headers: {Authorization: "Bearer " + result.access_token}
};
return rp(options).then(findings =>{
return findings;
});
});
};
module.exports = restaurants;
A few thoughts :
message.reply is thenable, therefore return message.reply() in two places.
request.converseText() is thenable, therefore return request.converseText(...).
restaurants is thenable, therefore return restaurants(...).
in message.js, message.addReply() is passed object of the form {type:..., content:...} in two places but finally just res. Is that correct?
in restaurants.js, Promise.all() appears to be unnecessary. It will cause its result to be wrapped in an array. module.exports = location => yelpCall(location); seems more appropriate.

Categories

Resources