Sqlite3 returning empty array with GET request in Express - express

I am trying to make a get request to an sqlite3 table, using Express, based on input from a form. The fetch request works and so does the db.all, but I receive a response as an empty array from rows. I tried req.query and req.params already. Not sure where the error is.
//server.js
app.get('/names/state', (req, res, next) => {
const stateValue = req.query.state;
db.all(`SELECT name FROM states WHERE name=$stateVal`,
{
$stateVal: stateValue
},
(err, rows) => {
res.send({rows:rows});
})
});
//script.js
const fetchOneBtn = (e) => {
e.preventDefault();
const stateVal = stateInputValue.value;
fetch(`/names/state?state=${stateVal}`)
.then(response =>{
if(response.ok){
return response.json();
}
}).then(names => {
console.log(names);
})
};

You can change your code in your backend with this code below:
app.get('/names/state', (req, res, next) => {
const stateValue = req.query.state;
var query = "SELECT name FROM states WHERE name = " + stateValue;
db.all(query, (err, rows) => {
if(err) {
console.log(err);
res.status(500).send(err);
}else {
res.send({rows});
}
})
});
Now, for your frontend, you can change with the code below:
const fetchOneBtn = async (e) => {
e.preventDefault();
const stateVal = stateInputValue.value;
try {
const response = await fetch(`/names/state?state=${stateVal}`, {
method: 'GET',
headers: {
'Content-Type': 'application/json'
},
});
console.log(await response.json());
return await response.json();
} catch(ex) {
console.log(ex);
}
};
I hope it can help you.

Related

Get API foreign key relation with Axios in VueJS

Context :
I make an API with API-Platform, and I consume this API with Vue 3 and HTTP client Axios
I have two entities in my API :
Author : name(string)
Text : content(string), author(relation to Author)
So a text item is relate to an Author...
Problem :
In Vue 3, I want to call my API for get Text entity.
But in the author column (<td> {{ item.author }} </td>) i have juste the URI reference (/api/authors/2) but I need the name of author...
Solution I tried :
<td> {{ getAuthor(item.author) }} </td>
(authorLink = /api/authors/2)
methods: {
getAuthor: async function (authorLink){
const res = await axios.get('http://127.0.0.1:8000' + authorLink)
console.log(res.data.name)
return res.data.name
}
Result of my solution :
With console.log() : 'JohnDoe' -> this work !
With return : '"[object Promise]"' -> this didnt work..
This way to get the return name with async/await pattern.
And axios needs a Accept-Encoding with correct format.
const getAuthor = async () => {
...
const res = await axios.get(...);
return Promise.resolve(res.data.name);
};
getAuthor()
.then(result => {
console.log(result);
})
Demo code
const axios = require("axios");
const getAuthor = async () => {
try {
const res = await axios.get('https://jsonplaceholder.typicode.com/users/1',
{
headers: {
'Accept-Encoding': 'application/json',
}
}
);
return Promise.resolve(res.data.name);
} catch (error) {
return Promise.reject(error);
}
};
getAuthor()
.then(result => {
console.log(result);
})
.catch(error => {
console.error(error);
});
Result this code
$ node get-data.js
Leanne Graham
This is express server version
const express = require("express")
const axios = require("axios")
const cors = require("cors")
const PORT = 3030
const app = express()
app.use(express.urlencoded({ extended: true }))
app.use(cors())
const getAuthor = async () => {
try {
const res = await axios.get('https://jsonplaceholder.typicode.com/users/1',
{
headers: {
'Accept-Encoding': 'application/json',
}
}
);
return Promise.resolve(res.data.name);
} catch (error) {
return Promise.reject(error);
}
};
app.get("/users/:id", async (req, res) => {
getAuthor()
.then(result => {
res.json(result)
})
.catch(error => {
console.error(error);
});
})
app.listen(PORT, (err) => {
if (err)
console.log("Error in server setup")
console.log("Server listening on Port", PORT);
})
install dependencies
npm install express axios cors
run it
$ node data-server.js
Server listening on Port 3030
Open this URL Chrome and open DevTool by F12
http://localhost:3030/users/1

Struggling to correctly make use of returned values from functions that are being called Asynchronously by Axios

I have an Express server which serves as an API Request forwarding tool (i.e my client calls the express server, and the express server forwards that call to another API).
The way this server is supposed to work is that there is a single entry point which makes a request, and then based on the response makes further API requests and returns a result based on the combo of API request responses.
To be clearer, the main logic is as follows:
Single entry point, which makes an async axios call to get an ID value
Within this function, we call an async function, getPartnerDetails (passing that ID as the parameter)
getPartnerDetailscalls a 3rd async function, '''getRawJson''' which is supposed to return the final required result, passing it back to '''getPartnerDetails''' which then passes it to the main entry point.
Whats going wrong is that the results are being recieved but are not being pass back correctly. The console logs within the '''.then(()=>{})''' of my async functions are coming back as '''undefined'''.
Code below:
app.post('/checkuser', async (req, res, next) => {
const { man, bfn, bln, bsn, bc, bs, bz, bco } = req.body;
const bodyContent = {
man: man,
bfn: bfn,
bln: bln,
bsn: bsn,
bc: bc,
bs: bs,
bz: bz,
bco: bco,
profile: 'DEFAULT',
};
try {
await axios
.post('https://host.com/im/account/consumer', bodyContent, { headers })
.then((response) => {
const addressValidResult = response.data.score.etr.filter(
(result) => result.test === '19:2'
)[0];
// console.log(res.json(result.details));
const requestId = response.data.mtid;
const currentValidAddress = getPartnerDetails(requestId).then(
(result) => {
console.log('this is currentvalidaddress ' + result);
res.json({
validationMessage: addressValidResult,
currentValidAddress: result,
});
}
);
})
.catch((err) => next(err));
} catch {}
});
async function getPartnerDetails(appId) {
let config = {
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic M2QzMsdfsslkfglkdjfglkdjflkgd',
},
params: {
partner: 19,
},
};
const res = await axios
.get(
`https://host.com/im/account/consumer/${appId}/partner/requests`,
config
)
.then((response) => {
const requestId = response.data.requests[0].request_id;
console.log('this is request id ' + JSON.stringify(requestId));
const raw = getRawJson(appId, requestId).then((result) => {
console.log('this is getRawJson result ' + JSON.stringify(result));
return JSON.stringify(result);
});
// https://host.com/im/account/consumer/:appId/partner/request/:requestId
})
.catch((err) => console.log('err2' + err));
}
async function getRawJson(appId, requestId) {
const res = await axios
.get(`host.com/im/account/consumer/${appId}/partner/request/${requestId}`, {
headers,
})
.then((response) => {
console.log('this is response ' + JSON.stringify(response.data));
return JSON.stringify(response.data);
})
.catch((err) => console.log('err1 ' + err));
}
It might have something to do with how I'm using async and await, I'm new to it so I'm hoping that I'll learn a thing or 2 more about it by solving this project.
I'm also aware that maybe I should split the entry point out into 3 different entry points, and have the client manage the chaining of the requests and responses instead.
Thanks!!
Probably an error due to incorrect async await usage.
Try to change your code like this:
app.post('/checkuser', async (req, res, next) => {
const { man, bfn, bln, bsn, bc, bs, bz, bco } = req.body;
const bodyContent = {
man: man,
bfn: bfn,
bln: bln,
bsn: bsn,
bc: bc,
bs: bs,
bz: bz,
bco: bco,
profile: 'DEFAULT',
};
try {
const { data } = await axios.post(
'https://host.com/im/account/consumer',
bodyContent,
{ headers }
);
const addressValidResult = data.score.etr.filter(
(result) => result.test === '19:2'
)[0];
const requestId = data.mtid;
const currentValidAddress = await getPartnerDetails(requestId);
console.log('this is currentvalidaddress ' + currentValidAddress);
res.json({
validationMessage: addressValidResult,
currentValidAddress: currentValidAddress,
});
} catch (err) {
next(err);
}
});
async function getPartnerDetails(appId) {
let config = {
headers: {
'Content-Type': 'application/json',
Authorization: 'Basic M2QzMsdfsslkfglkdjfglkdjflkgd',
},
params: {
partner: 19,
},
};
const { data } = await axios.get(
`https://host.com/im/account/consumer/${appId}/partner/requests`,
config
);
const requestId = data.requests[0].request_id;
console.log('this is request id ' + JSON.stringify(requestId));
return getRawJson(appId, requestId);
}
function getRawJson(appId, requestId) {
return axios
.get(`host.com/im/account/consumer/${appId}/partner/request/${requestId}`, {
headers,
})
}

not playing audio from buffer stored in the database

I've spent 2 days with this thing and couldn't find a solution but seems like im getting closer. The goal is to record audio in the browser and store in the the database and get it whenever i need it.
I encoded the audio to base64 and sent it to the server stored as binary in the mongodb, created a get route in which i find the audio by id and send the buffer via res.send() along with the content type set to audio/webm (default mime type)
but the thing is I'm getting this blank video, seems like it's not knowing how to decode it or something. There might be something wrong with the content type.
navigator.mediaDevices.getUserMedia({ audio: true, video: false })
.then((mediaRecorderObj) => {
let mediaRecorder = new MediaRecorder(mediaRecorderObj, { mimType: 'audio/webm;base64' })
const m = mediaRecorder;
let chunk = []
startBtn.addEventListener('click', () => {
mediaRecorder.start()
console.log('started recording..');
})
endBtn.addEventListener('click', () => {
mediaRecorder.stop()
console.log('just stopped recording');
})
//-----When Data Is Available
mediaRecorder.ondataavailable = (e) => {
chunk.push(e.data);
}
//--------When finished adding it to chunk
mediaRecorder.onstop = () => {
const blob = new Blob(chunk, { 'type': 'audio/webm' })
chunk = []
const reader = new FileReader()
reader.readAsDataURL(blob)
reader.onloadend = async () => {
const buffer = reader.result
const bodyObj = {
voice: buffer
}
await fetch('http://localhost:3000/upload-spoken-bio', {
method: 'post',
body: JSON.stringify(bodyObj),
headers: { 'Content-Type': 'application/json' }
})
}
}
})
and this is the server side
//----------Upload
spokenBio.post('/upload-spoken-bio', async (req, res) => {
const buffer = req.body
try {
const newBuffer = new SpokenCon(buffer)
await newBuffer.save()
}
catch (err) {
console.log(err.message);
}
})
//----------Retrieve
spokenBio.get('/get-spoken-bio/:id', async (req, res) => {
const id = req.params.id
try {
const field = await SpokenCon.findById(id)
const binary = field.voice
res.set({ 'Content-Type': 'audio/webm' })
res.send(binary)
}
catch (err) {
console.log(err.message);
}
})

How to passing result of http request inside async in ExpressJS?

I have below code
async send(user, data) {
const postData = {
'data': 'john',
'secret': 'secret'
};
const dataJson = JSON.stringify(postData);
const options = {
hostname: 'example.com',
path: '/send',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': dataJson.length
}
};
const req = https.request(options, (res) => {
let data = '';
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: ", err.message);
});
req.write(dataJson);
req.end();
//---------------
let postResult = // HERE I WANT TO GET WHAT HTTP POST REQUESTED (e.g dataJson.body?)
//---------------
let result;
try {
result = await this.users.collection('users').updateOne(
{
_id: user
},
{
$set: {
// I WANT TO USE THAT HERE
data1 : postResult,
data2 : data2
}
},
{ maxTimeMS: consts.DB_MAX_TIME_USERS }
);
} catch (err) {
log.error('DB', 'UPDATEFAIL id=%s error=%s', user, err.message);
err.message = 'Database Error, failed to update user';
err.code = 'InternalDatabaseError';
throw err;
}
return { success: true };
}
How to get those data to outside variable?
I almost crazy about this, been searching on google and not found anything
I am using express and native-http to make http request, are there any native-curl maybe?
thank you very much for all the help
Your current code is using callback to retrieve result, so you can initiate data variable to outside callback function
let data = '';
const req = https.request(options, (res) => {
console.log('Status Code:', res.statusCode);
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Body: ', JSON.parse(data));
});
})
And also there are other easier way to make http request with nodejs. you can check axios that support Promise and async/await.
you can use syntax like this with axios
const response = await axios.get('/user?ID=12345');
way more easier.

Send single response after multiple updates

I have an array of items that I am passing to an API endpoint (using Sequelize as my ORM). I'm trying to iterate over each item and update it, however I'm getting a Unhandled rejection Error: Can't set headers after they are sent.
stepsController.put = (req, res) => {
const { steps } = req.body;
// Steps is an array of objects that I want to update...
steps.map(step => {
Step.findOne({ where: { id: step.id } })
.then(savedStep =>
savedStep
.update({
order: step.order,
})
.then(success => res.status(200).send(success))
.catch(error => res.send(error))
)
.then(ok => res.status(200).send(ok))
.catch(err => res.send(err));
});
};
I believe this is because it's sending the response for each item. Sequelize's update method is a promise. How can I iterate over all of the items and make sure all of the items are updated before sending a single successful response?
There are three ways you can do
Promise.all
Co
Async Await
1) Here it is , you can use Promise.all :
stepsController.put = (req, res) => {
const { steps } = req.body;
// Steps is an array of objects that I want to update...
Promise.all(steps.map(step => {
return Step.findOne({ where: { id: step.id } }).then(savedStep =>
return savedStep.update({
order: step.order,
})
.catch(error => error)
).catch(err => err)
}))
.then(ok => res.status(200).send(ok))
.catch(err => res.send(err));
};
2) Another way is to use co :
const co = require('co');
stepsController.put = co.wrap(function* (req, res) => {
try {
const { steps } = req.body;
// Steps is an array of objects that I want to update...
for(let i=0;i<steps.length ; i++) {
let savedStep = yield Step.findOne({ where: { id: steps[i].id } });
if(savedStep)
yield savedStep.update({ order: steps[i].order});
}
res.status(200).send();
}
catch(err){
res.send(err);
}
});
3) If you’re using Node 8.0+ , there is no need of any package you can directly use async await :
stepsController.put = async(req, res) => {
try {
const { steps } = req.body;
// Steps is an array of objects that I want to update...
for(let i=0;i<steps.length ; i++) {
let savedStep = await Step.findOne({ where: { id: steps[i].id } });
if(savedStep)
await savedStep.update({ order: steps[i].order});
}
res.status(200).send();
}
catch(err){
res.send(err);
}
};