I face a new problem that has been asked before in this link. But It is not relevant to my problem.
What I have implemented is a very simple API using nodejs, express-framework and mongoose.
The problem is with fetch API. I want to submit some ID and post it to the server. In the server side I redirect it to the proper URL base on the ID that user entered. Whenever I test this part, this error is being raised in front-end side and points to return response.json() line.
SyntaxError: Unexpected end of input
Here is my code:
Front-End:
function submitCode(){
var nationalCode = document.getElementById('nationalCode').value
var data = {
nationalCode: nationalCode,
creationDate: new Date().toLocaleDateString()
}
fetch('/submit', {
method: 'POST',
redirect:'manual',
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
},
body: JSON.stringify(data)
},
).then(response => {
return response.json()
}).then(jsonData => {
console.log('success:', jsonData)
history.pushState(null, null, "/lashkhor")
}).catch(e => {
console.log('error:', e)
return e
})
}
Back-End:
app.post('/submit', (req, res) => {
var nationalCode = req.body.nationalCode
var creationDate = req.body.creationDate
query = {'nationalCode': nationalCode}
nationalCodeModel.find(query, (err, success) => {
if (err) {
console.log('error:', err)
}
else if (success.length == 0){
nationalCodeModel.create({
nationalCode: nationalCode,
creationDate: creationDate
})
console.log('salam khoshgele daei!')
res.redirect('/khoshgeledaei')
}
else if (success.length > 0) {
console.log('lashkhor detected')
res.redirect('/lashkhor')
}
})
})
app.get('/lashkhor', (req, res) => {
console.log('here')
res.send('salam')
})
I can't find any hint to solve it. I would be thankful if anyone could help me.
PS: Whole code is available in this repository
Thanks!
You are trying to parse text into json.
You can use res.json() instead of res.send() from your backend.
Related
I'm sure I probably have something simple to fix, but have tried and tried and cannot find it. I have several API calls that are working just fine. But I have made a new one, which I made by copy and pasting ones that worked, and just changing values and names. But this new one, gives me a 500 error.
The API path should be:
"http://localhost:3000/billingcalculator/create"
Instead, it is:
"http://localhost:3000/undefined/billingcalculator/create" <-- where is the undefined coming from?
It gives this error:
PUT http://localhost:3000/undefined/billingcalculator/create 500 (Internal Server Error)
It references the line in the call that says throw new Error() ; but I don't see what's wrong with that. I use that exact same code all over the place and it works fine everywhere else.
Call that works perfectly:
createHCA() {
fetch(API_URL + `/hca/create`, {
method: "PUT",
body: JSON.stringify({
client: this.state.client,
short: this.state.short,
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
.then(() => this.getHCAid())
.then(() => this.getAllHCAs());
this.setState({ showHide: false});
}
And this is the call that creates the error and cannot reach my API routes:
createBillProject() {
fetch(API_URL + `/billingcalculator/create`, {
method: "PUT",
body: JSON.stringify({
client: this.state.client,
source: this.state.source,
projectName: this.state.projectName
}),
headers: { "Content-Type": "application/json" },
})
.then((res) => {
if (!res.ok) {
throw new Error();
}
return res.json();
})
.then((data) => console.log(data))
.catch((err) => console.log(err))
.then(() => this.getBillProjLastId());
}
The API route I'm trying to reach is this:
app.put("/billingcalculator/create", function (req, res) {
console.log("It is getting to the billing route");
const client = req.body.client;
const source = req.body.source;
const projectName = req.body.projectName;
console.log(`client: ${client}`);
console.log(`source: ${source}`);
console.log(`project name: ${projectName}`);
connection.getConnection(function (err, connection) {
connection.query(
`INSERT INTO billcalc_projects (client, source, project_name)
VALUES (?, ?, ?)`,
[client, source, projectName],
function (error, results, fields) {
connection.release();
if (error) throw error;
res.json(results);
console.log(`Billing Project has been created`);
}
);
});
});
Thanks in advance for your help. It must be something simple that I'm just missing. But I haven't been able to figure it out.
I'm trying to doing a basic GET request from ReactJS app to a Node.js API, but I'm getting a response with status 304. I need get a 200 status to save the response of GET in a variable. (Im running Reactjs app in port 3000 and Nodejs API in port 3300)
Node API:
app.get('/serviciosextras', async (req, res) => {
let connection;
console.log(('Servicios Extras'));
try {
connection = await oracledb.getConnection({
user: 'portafolio',
password: '123',
connectString: "localhost:1521/orcl"
});
const result = await connection.execute(
`SELECT dep.id_departamento,
se.id_servicio,
se.precio_servicio
FROM departamento_servicio_detalle dsd
JOIN departamento DEP ON (dsd.id_departamento = dep.id_departamento)
JOIN servicio_extra SE ON (dsd.id_servicio = se.id_servicio)
ORDER BY 1 ASC`
)
const resultSet = result.rows;
let lista = [];
resultSet.map(obj => {
let serviciosSchema = {
'id_departamento': obj[0],
'id_servicio': obj[1],
'precio_servicio': obj[2]
}
lista.push(serviciosSchema);
});
console.log(lista);
res.json(lista);
connection.close();
} catch (err) {
console.error(err);
}
});
GET request from Reactjs
const getExtraServices = () => {
let endpoint = `${URL}serviciosextras`;
const requestOptions = {
method: "GET",
mode: 'no-cors'
// headers: {
// "Content-Type": "application/json",
// Accept: "application/json"
// },
};
console.log(endpoint);
fetch(endpoint, requestOptions)
.then((res, err) => {
console.log(res);
})
.then(result => {
console.log('fue aqui');
console.log(result);
})
.catch(err => {
console.log('ERROR');
console.log(err);
})
}
Im calling the method from this button:(onClick={getExtraServices()})
<Fab onClick={(e) => {
e.preventDefault();
getExtraServices();
}} variant="extended">
<NavigationIcon style={{marginRight: 'theme.spacing(1)'}} />
Navigate
</Fab>
so... I'm getting this:
Firefox Console when I clicked button to call getExtraServices() res is undefined
Network console of GET request I got a response but the status is 304, so I can't get this from code. :/
Console of Nodejs API this console.log if from console.log(lista) before send the res.json(lista)
Does someone know how can I fix this? I need get the response of the GET request to charge a list in ReactJS app, but I can't because the response has body:null.
Error 304 isn't the problem.
It looks like you are missing a statement to turn your response into JSON.
Here's an example from MDN:
fetch('https://example.com/profile', {
method: 'POST', // or 'PUT'
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(data),
})
.then(response => response.json())
.then(data => {
console.log('Success:', data);
})
.catch((error) => {
console.error('Error:', error);
});
In particular:
.then(response => response.json())
In your code:
fetch(endpoint, requestOptions)
.then((res, err) => {
console.log(res); // logging res
// no data being returned here
})
.then(result => {
console.log('fue aqui');
console.log(result); // therefore result is undefined
})
.catch(err => {
console.log('ERROR');
console.log(err);
})
I am stuck on one of the mysterious issue. The problem goes like this:
What I Do??
Simply do login api call and if login success then I have to fetch amount of data from 5-6 api calls and store them in local database (Realm). Here is my code.
login(email, password) {
this.toggleLoadingFunction(true);
fetch(LoginURL, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
email: email,
password: password,
request_from: 'mobile'
}),
})
.then(async res => {
if (res.ok) {
let data = await res.json();
global.user = data['user']
global.token = data['token']
getAllMasterDataAndSaveInRealm().then(() => {
this.toggleLoadingFunction(false);
global.storage.save({ key: 'LoggedInData', data: data });
this.props.navigation.navigate('Project', data);
}).catch(() => {
this.toggleLoadingFunction(false);
Alert.alert("Master Data Failed !!!");
})
} else {
this.toggleLoadingFunction(false);
let data = await res.json();
Alert.alert("Login Failed!!!", data.message)
}
})
.catch(error => {
this.toggleLoadingFunction(false);
Alert.alert("Network Error. Please try again.")
})
Here getAllMasterDataAndSaveInRealm() is lies on helper function which calls 5-6 apis and response back if all work is done. Here is how it looks like:
export const getAllMasterDataAndSaveInRealm = () => {
const token = global.token;
return new Promise.all([
getMaterials(token),
getEquipments(token),
getObjective(token),
getCategories(token),
getNcData(token),
getPlans(token)]
);
}
Each function inside getAllMasterDataAndSaveInRealm() returns Promise after successfully stored data in local realm db. Here is one of the above function.
export const getActivityPlan = (token) => {
return new Promise((resolve, reject) => {
return fetch(FetchActivityPlanDataURL, {
method: 'GET',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
'access_token': `${token}`
}
}).then((response) => {
console.log("Activity Plans Api response", response);
return response.json()
})
.then((responseJson) => {
const { data } = responseJson
console.warn("Activity Plans Api", data);
global.realm.write(() => {
for (var item of data) {
item.id = item.id ? item.id : 0;
item.activity_id = item.activity_id ? item.activity_id.toString() : "";
item.activity_name = item.activity_name ? item.activity_name.toString() : "";
item.activity_cost = item.activity_cost ? item.activity_cost.toString() : "";
item.project_id = item.project_id ? item.project_id : 0;
global.realm.create("ActivityPlan", item, true);
}
})
resolve(data);
})
.catch((error) => {
reject(`Activity Plan Failed ${error}`)
});
})
}
All remaining functions are same as above ( what they do is simply fetch data from api and store it in realm and resolve or reject)
What I Expect:
getAllMasterDataAndSaveInRealm() function Just store all the required data in db and let me know all done and then navigate to the another screen, as Login and fetching data is done.
Problem:
When I do run the app and process for login, Sometimes it works fine but most of the time App stuck on showing loader since some of the api call among 6 api from above do not get response from the request ( I do log the response) on wifi. But when I use mobile data and VPN it always works.
When I log request on server console, response is sent with code 200, but app is unable to get response for the request.
I am new on react native. I do lots of searches over internet but unable to find the solution. I don't have any idea whats going wrong with the code. Please help me out.
Project Configurations:
"react": "16.8.6",
"react-native": "0.60.4",
"realm": "^2.29.2",
Node version: v9.0.0
what I´m trying to do is the following I already set a fetch connection from client side JS to the server Node.JS when a person click on a button in HTML which triggers that in the server side looks for an element in the MongoDB database in it find´s it, but my question is how do I send that found element back to the client side JS.
Javascript Code:
var button = document.getElementById("1");
button.addEventListener("click", idss);
function idss() {
var id = this.id;
var data = {
name : id
}
fetch("/clicked", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(function(response) {
if(response.ok) {
console.log('awesome');
return;
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}
NODE JS:
app.post("/clicked", (req, res) => {
var pro = (req.body.name);
Number(pro);
Product.findOne({"id": pro}, function(err, foundLList) {
if(err) {
console.log(err);
} else {
console.log(foundLList); //THE ELEMENT IS FOUND
}
}
);
});
What I´m trying to do is to send the found element to Javascript so I can added to another variable.
You have to use res object to send data back to client. Your node code will be:
app.post("/clicked", (req, res) => {
var pro = (req.body.name);
Number(pro);
Product.findOne({
"id": pro
}, function(err, foundLList) {
if (err) {
console.log(err);
return res.status(500).json({
ok: false,
error: err
});
} else {
console.log(foundLList); //THE ELEMENT IS FOUND
return res.status(200).json({
ok: true,
data: foundLList
});
}
});
});
and on client side, you can read the data like this:
fetch("/clicked", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data)
})
.then(response => response.json())
.then(function(response) {
if (response.ok) {
console.log('got data: ', response.data);
}
throw new Error('Request failed.');
})
.catch(function(error) {
console.log(error);
});
}
This is very complicated term for me because i am confused how things are done. I have React & Express application where you can upload data and when you upload it will redirect you to other page where your data is displayed, but problem is that it only redirects you one time and when you go back to main page and try to upload file second time it is not uploaded and whole application crashes
here is recipe.js file (part of it) (react)
axios({
method: 'post',
url: '/api/recipes',
config: {headers: {'Content-Type': 'multipart/form-data' }},
data: data
})
.then(res => {
window.location.replace(res.data.location)
})
.catch(err => {
if(err.response){
if(err.response.data.redirect === true){
window.location.replace(err.response.data.location)
}
if(err.response.data.message){
alert(err.response.data.message)
}
}
});
recipe.js (part of it)(expressjs)
const recipe = await Dish.create({
author: user.username,
name: name,
//properties and values
})
return res.status(200).send({
location: '/recipe/' + recipe.name + '/' + recipe._id
})
view-recipe.js (express (part))
componentDidMount(){
const { match: { params } } = this.props;
console.log(`/api/recipe/${params.dishName}/${params.id}`)
axios.get(`/api/recipe/${params.dishName}/${params.id}`)
.then(res => res.data)
.then(data =>{
console.log(data)
}).catch(err=>{
if(err.response.data.message){
alert(err.response.data.message)
}
})
}
view-recipe.js (express)
router.get('/:dishName/:id', async (req, res) => {
try {
const name = req.params.dishName;
const id = req.params.id;
console.log('name ' + name + ' id ' + id)
const recipe = await Dish.findOne({
name: name,
_id: id
}).lean();
if (!recipe) {
return res.status(404).send({
message: 'recipe not found'
})
}
return res.status(200).send({
recipe
})
} catch (err) {
return res.status(500).send({
message: err.message
})
}
})
and finally
index.js (express, for where is guard determinig whether jwt validation token is expired or not and route configurations )
router.use('/api/recipes', guardr, require('./recipe'))
router.use('/api/recipe', require('./view-recipe'))
What is wrong with this code? By the way, before window.location.replace() in recipe.js file (client) i had window.location.href instead and it worked 2 times. it is really confusing for me because i am doing this difficult project for the first time. Thanks!