So I'm trying to learn nodeJS.. But something wierd is happening. When I try to make a GET or a POST request it keep requesting infinitly on the localhost. I tested with a simple piece of code just requesting a simple Hello Word but it still doesnt works. It was working perfectly yesterday.
I tested insomnia, postman and the browser. If someone can help me would be very nice, cause I'm really stucked here...printscream of the insomnia infinity request
const {json} = require('express');
const express = require('express');
const {uuid} = require('uuidv4');
const app = express();
app.use(express,json);
const projects = [];
app.get('/projects', (request, response) => {
return response.json(projects);
});
app.post('/projects', (request, response) => {
const {title, owner} = request.body;
const project = {id: uuid(), title, owner };
projects.push(project);
return response.json(project);
});
app.listen(3333, () => {
console.log('Working đź‘Źđź‘Ź')
});
It's just two little mistakes. Take in mind that express.json() is a method, so you need to put it like this:
app.use(express.json())
You are using a comma instead of a point. However, you have done a destructuring of the .json () method; therefore, you do not have to prepend express; it would look like this:
app.use(json())
On the other hand, you probably have an unwanted result in the post request since you send the project variable instead of projects. Be sure that is what you want.
Related
This is my function
export const testFunction = functions.https.onRequest((req, res) => {
const text = req.body.text;
res.set("Access-Control-Allow-Origin", "*");
res.send({text: text});
});
i've tried using const cors = require('cors')({origin: true});
I keep getting this as a response. Does anyone know why?
Consider importing like this,
const cors = require('cors')({origin: true});
And try running the below function using firebase deploy –only functions :
const functions= require("firebase-functions");
const cors = require('cors')({origin: true});
exports.testFunction = functions.https.onRequest((req, res) => {
cors(req, res, () => {
const text = req.body.name;
res.send({text:text});
});
});
And then send request using :
curl -X POST "https:/region-projectID.cloudfunctions.net/function-name" -H "Content-Type:application/json" --data '{"name":"Keyboard Cat"}'
The output I am getting in the console is :
And when I click on the Cloud Function URL endpoint, my output is an empty {}.
If you try res.send(“Hello World”) in place of res.send({text:text}), you will get the output in the browser as Hello World but since our Cloud Function performs some contrived operation using data passed in the request body.This could result in an error at run time if the property name is null or undefined.
And indeed, if we deploy this new function and then attempt to call it from our web app without updating our request we do get an error. However, it might not be the error you’d expect.
It’d be easy to assume that we somehow misconfigured our CORS policy. Infact swapping cors() to cors({ origin: '*'}) to cors({ origin: true}) all to no avail. Only when we view the logs for our Cloud Function do we get a useful error message.
So try sending a POST request with the –data flag, or if you are using Postman, send the data and the parameters. Then only you would be able to have an output, if you still see the CORS error, check if your function is handled well or your nested request body attribute is not undefined/null. Sometimes CORS errors are not always CORS!
I have a system in place where I have a nodejs app:
app.post('/action', (req, res) => {
...
const option = req.body.option
...
switch (option) {
case 'getinfo':
objectToSend = {"foo": "bar"}
// i tried using
res.json(objectToSend)
// and
res.send(JSON.stringify(objectToSend))
// but neither got me anywhere
break
}
And a website that sends a post request using fetch like this (infoModal is the function I use to display data) (I got the action function sent on discord and have been using it since then, but ive never had to do anything with the response)
let action = async (i) => {
res = await fetch("/action", {
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
method: "POST",
body: JSON.stringify(i)
})
return await res.json
}
action({
option: 'getinfo'
}).then(j => {
infoModal(j.foo,'ok')
})
I can't really fix either the backend or frontend since both have to work for me to confirm it works...
EDIT:
These are my requires, uses and sets:
require('dotenv').config()
...
const express = require('express')
const path = require('path')
var bodyParser = require('body-parser')
let ejs = require('ejs')
const fs = require('fs')
var cookieParser = require('cookie-parser')
var colors = require('colors')
const app = express()
app.use(bodyParser.json())
app.use(cookieParser())
app.set('views', path.join(__dirname, 'frontend'))
app.set('view engine', 'ejs')
One obvious mistake is not executing the jeson() method of the Fetch response. And, although harmless, the second await statement is not really necessary - the async functions anyway wrap what is returned in a promise.
return res.json();
If that doesn't work -
See what your developer console says. It should give you lot of information about the request. If there is an error, follow the info (response code, any error message etc) and try to determine the problem.
Use a rest client such as POSTMAN to verify your backend first. When you know that it can respond well to a proper request, you can try your front-end with confidence and get more understanding on how the response should be handled.
Not a pro with things like server middleware, but stuck without much clues.
In a vue component I am retrieving data with axios with this:
axios
.get('/api/getDailyFeedback', {
params: {
start: '2018-05-01'
}
})
Which goes to the express (version 4.16.2) server middleware setup in Nuxt. I have gotten normal get and post requests to work fine but the problem is when I want to pass in a parameter into a get request like the below:
router.get('/getDailyFeedback', (req, res) => {
console.log('Query:', req.query.start);
//do stuff
});
What little experience I had with Express 4, it took me a little bit of time to realise why parameters passed in the body of a post request were undefined, but it was because I needed to add body-parser.json() to my nuxt config since they removed that from the main express package. Similarly I thought I needed bodyParse.urlencoded but that has not worked. This is the line I added to my nuxt.config:
serverMiddleware: [bodyParser.urlencoded({ extended: false }), bodyParser.json(), '~/api'],
I am unsure if the content type is not set correctly or I am missing something simple here. I know I am able to use various libraries to grab the parameters from the url string which I have access to, as Axios is working as expected and adding my 'params' object onto the end of my get request. But a lot of solutions I have seen to other problems is 'oh its as simple as accessing req.query' Alas Express fails to define a req.query object, or even req.params or req.body.
Hopefully that is enough detail to go on, thanks a lot for reading and any suggestions.
Well that's an unpleasant surprise to try to use the get request in Nuxt for the first time, isn't it? Nuxt creates a connect instance which leads to some pitfalls. It's req is the Node.js http request object, so it doesn't have the query property and request.body is also being skipped in get requests!
But there is a way for everything. Your code:
axios.get('/api/getDailyFeedback', {
params: {
start: '2018-05-01'
}
})
Translates to the following URI call:
/api/getDailyFeedback?start=2018-05-01
So you've got all the params in the URI where you can retrieve them from via url parsing. Module url ships with Node.js by the way.
const url = require("url");
router.get('/getDailyFeedback', (req, res) => {
let queryData = url.parse(req.url, true).query
console.log('Query:', queryData.start)
});
I wrote a little helper that extends req with a custom property. Here's the code:
router.use((req, res, next) => {
var theQuery = url.parse(req.url, true).query
req.queryData = theQuery
next()
})
Then you can use it like this:
router.get('/getDailyFeedback', (req, res) => {
console.log('Query:', req.queryData.start)
});
Other way to pass params via get is by using optional uri segments:
router.get('/getDailyFeedback/:start?', (req, res) => {
console.log('Query:', req.params.start)
});
I am using Nuxt 2.15 and I can access the query parameter like this req._parsedOriginalUrl.query
You can access Nuxt get params without additional modules.
Just use:
req.request.get()
For anyone else in the future
const { Router } = require('express')
Router.get('/orders', async (req, res, next) => {
const request = req.query.sometext;
res.json({data: request});
});
module.exports = Router;
<script>
export default() {
async mounted() {
const orders = await axios.get(`/api/orders`, {
params: {
sometext: 'bla bla'
}
});
}
}
</script>
http://expressjs.com/en/api.html#req
I have very basic application at the moment that I wanted to try to implement SSR with.
problem 1
Previously I would send index.html (that had a script tag with my bundle.js inside) to requests made to '/' and that would render on the client.
Now I'm rendering the app on the server for every request made to '/' and now, expectantly, when I make GET requests to '/api/users/' my isomorphic rendering function is executed (even though this is an API request and should not be rendering anything).
I understand why, because of where I placed this function in the middleware is such that all requests made to the app will run that middleware.
My question is: How can I ignore this function unless a browser is requesting it? Is that even the right question? It sounds like I'm asking for a hack, which means I'm misunderstanding something.
problem 2
This is the cause of another problem I am having when the client requests bundle.js. Because each request is rendering the app and sending html back, requests to get the bundle are receiving an HTML response, which when parsed by the browser errors out as expected (Unexpected token '<').
I think I've designed my server poorly, and maybe someone can give me some insight or point me to a good place to start learning.
server.js
require('babel-register')
var express = require('express')
// TODO setup global error handling
var path = require('path') // built-in middleware
var mongoose = require('mongoose')
const isomorphic = require('./isomorphic')
// change promise library of mongoose to bluebird
mongoose.Promise = require('bluebird')
// create the api and auth
var api = require('./api/api')
var auth = require('./auth/routes')
// make app
var app = express()
// setup the app middleware
require('./middleware/appMiddleware')(app)
// get the api and auth
app.use('/api', api)
app.use('/auth', auth)
// serve static assets
app.use(express.static('dist'))
// serverside rendering
app.use(isomorphic)
// give the bundle
// app.get('/dist/bundle.js', function(req, res) {
// res.sendFile(path.resolve('dist/bundle.js'), function(err) {
// if (err) {
// res.status(500).send(err)
// }
// })
// })
module.exports = app
Note app.get('/dist/bundle.js', function... is commented out because I believe app.use(express.static('dist)) should be handling that. Right?
isomorphic.js
var React = require('react')
var ReactDOMServer = require('react-dom/server')
var StaticRouter = require('react-router-dom').StaticRouter
var ServerStyleSheet = require('styled-components').ServerStyleSheet
var fs = require('fs')
var _ = require('lodash')
var baseTemplate = fs.readFileSync('./index.html') // TODO change to async function maybe
var template = _.template(baseTemplate)
var sheet = new ServerStyleSheet()
var something = sheet.collectStyles(App)
var css = sheet.getStyleTags()
var App = require('../src/js/App').default
const isomorphic = (req, res) => {
var context = {}
var body = ReactDOMServer.renderToString(
React.createElement(StaticRouter, { location: req.url, context },
React.createElement(App)
)
)
console.log('hello?');
if (context.url) {
// TODO if there is a redirect
}
res.write(template({body: body}))
res.end()
}
module.exports = isomorphic
Please let me know if you need to see any other files.
update 1
I added a check in isomorphic.js that looks like this:
if (req.url !== '/') {
next()
} else {
...
}
And I uncommented the app.get('/dist/bundle.js') code.
Now everything seems to be half working, however:
That if check seems to be bad practice because the user could request routes that exist on the client that are not the root.
React's server render does match the checksum on the client, therefore negating the SSR.
And the app.use(express.static('dist')) appears to be doing absolutely nothing. The 'dist' directory is one level up from my server.js file, so I've changed it to '../dist' but it still 404s (with that .get commented).
update 2
I have figured out why express.static('dist') was not working.
One, I changed it from express.static('dist') to express.static(path.join(__dirname, '../dist/')) to be sure it going to the correct path.
Two, in my index.html, the script tag was originally
<script src="dist/bundle.js"></script>
when apparently it should have been this (I got lucky and guessed this could have been the issue)
<script src="bundle.js"></script>
const express = require('express');
var router = express.Router()
const app = express();
const pgp = require('pg-promise')();
const pug = require('pug');
const connect = require('../core/connect.js');
const model = require('../models/model.js');
app.get('/data',function (req, res)
{
const data = model.getData(connect.db, 'Select * FROM items');
res.send(data);
});
Looking at the code here, I should be able to use the getData function from model because I required it within the actual get request to data. However for some reason, it does not seem to be performing the query. I have verified the data does exist through postgres. I also know that if I move the const data line out of the app.get, it also works.
Can someone please explain how I used my functions from the model.js file within GET and POST requests?
I'm not using Ajax or Jquery. I read through that article and I'm still not sure what exactly I'm missing. It is saying something about a callback, but I'm not too clear on that either.