I am writing a serverless netlify function when I hit /:uid endpoint, it shows me this error message n is not a function but when I hit / endpoint, it doesn't throw an error.
Please help me with this.
src/api.js file code
const express = require("express");
const cors = require("cors");
const fetch = require("node-fetch");
const helmet = require("helmet");
const serverless = require("serverless-http");
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}
const app = express();
const router = express.Router();
app.use(cors());
app.use(helmet());
const fetchWithToken = (endpoint, method = "GET") => {
return fetch(`${process.env.API_BASE_URL}${endpoint}`, {
method,
headers: {
Authorization: `token ${process.env.TOKEN}`,
},
});
};
router.get("/", (req, res) => {
res.send("JDKJKFJ");
});
router.get("/:uid", async (req, res) => {
try {
const data = await fetchWithToken(`/${req.params.uid}`, "GET");
res.status(200).json(data);
} catch (error) {
console.log(error.message);
res.status(500).json({ error });
}
});
app.use("/.netlify/functions/api", router);
module.exports.handler = serverless(app);
error message
TypeError: n is not a function
at /Users/rishipurwar/codingspace-proxy-server/functions/api.js:159:3133
at /Users/rishipurwar/codingspace-proxy-server/functions/api.js:159:3232
at o.handle_request (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:120:783)
at o (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:113:879)
at d.dispatch (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:113:901)
at o.handle_request (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:120:783)
at /Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:2533
at f (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:3502)
at f (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:3696)
at Function.v.process_params (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:3839)
at g (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:2476)
at Function.v.handle (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:3340)
at p (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:238)
at o.handle_request (/Users/rishipurwar/codingspace-proxy-server/functions/api.js:120:783)
at /Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:2905
at /Users/rishipurwar/codingspace-proxy-server/functions/api.js:106:2927
Response with status 500 in 57 ms.
You need to add .json() to the returned value from fetch:
try {
let data = await fetchWithToken(`/${req.params.uid}`, "GET");
data = await data.json()
res.status(200).json(data);
} catch (error) {
console.log(error.message);
res.status(500).json({ error });
}
Related
Error: Failed to load function definition from source: Failed to generate manifest from function source: Error: Route.get() requires a callback function but got a [obj Undefined]
Here, the endpoints will be '/EmpDeleteAll'
Index.js
const express = require("express");
const cors = require("cors");
const db = require("./models");
const app = express();
const EmpFunction = require('./controllers/emp.controller')();
const functions = [
{ name: "Emp", function: EmpFunction }
];
app.use(cors({
origin: '*',
methods: 'GET, POST, DELETE, PUT',
allowedHeaders: 'X-Requested-With,Content-Type, Accept'
}));
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.get("/", (req, res) => {
res.json({ message: "Welcome to HR application API" });
});
functions.forEach(func => {
const { name, function: funcObject } = func;
app.post(`/${name}DeleteAll`, funcObject.deleteAll);
});
db.mongoose.connect(db.url, {
useNewUrlParser: true,
useUnifiedTopology: true
})
.then(() => {
console.log("Connected to the database!");
})
.catch(err => {
console.log("Cannot connect to the database!", err);
process.exit();
});
emp.controller.js
const db = require("../models");
const Employee = db.employee;
const functions = require("firebase-functions");
const cors = require('cors')
const express = require('express');
const router = express.Router();
// Delete all Employees
exports.deleteAll = (req, res) => {
Employee.deleteMany({})
.then(data => {
res.send({
message: `${data.deletedCount} Employees were deleted successfully!`
});
})
.catch(err => {
res.status(500).send({
message:
err.message || "Some error occurred while removing all Employees."
});
});
};
module.exports = router;
Dont know Why m receving above error, I guess doing something wrong with router, may be I need to assign response value to it, but dont know how ?
Can you please help findout cause and solution for above error ? many thanks
Remove Router part, from emp.controllers.js file,
Next, add below line at the end of Index.js
const firebase = require("firebase-functions");
exports.app = firebase.https.onRequest(app);
When I m trying to test my GET API using postman it returns 200 but with an empty body, The data I'm expecting to get do not show up.
Find my server.js file and the screenshot of POSTMAN result
app.get('/api/articles/:name', async (req, res) => {
try {
const articleName = req.params.name;
const client = await MongoClient.connect('mongodb://localhost:27017', { useNewUrlParser: true });
const db = client.db('my-blog');
const articleInfo = await db.collection('articles').findOne({ name: articleName })
res.status(200).json(articleInfo)
client.close()
}
catch (error) {
res.status(500).json({ message: 'error connecting to db', error })
}
})
here i have updated your code as below and please move your server.js outside of /src folder. its working now.
const express = require('express')
const bodyParser = require('body-parser')
const {MongoClient} = require("mongodb");
const url = 'mongodb://127.0.0.1:27017';
const app = express();
app.use(bodyParser.json());
app.get('/api/articles/:name', async (req, res) => {
try {
const articleName = req.params.name;
MongoClient.connect(url, async (err, db) => {
const client = db.db('article');
const articleInfo = await client.collection('articles').findOne({title: articleName})
res.send(articleInfo)
});
} catch (error) {
res.status(500).json({ message: 'Error connecting to db', error });
}
});
app.listen(8000, () => console.log('Listening on port 8000'));
I'm working on a node.js application.
In my application the requests are going through a middleware which checks if the user is authenticated. In my middleware file though, I keep getting the "next is not defined" error back in my client. What might be the issue? I'm adding the App.js and the middleware file in here:
App.js:
const express = require('express');
const cors = require('cors');
const bodyParser = require('body-parser');
const graphqlHttp = require('express-graphql');
const { sequelize } = require('./models');
const graphqlSchema = require('./graphql/schema');
const graphqlResolver = require('./graphql/resolvers');
const auth = require('./middleware/auth');
// return instance of the app
app = express();
// setting up the cors config
app.use(cors({
origin: '*'
}));
// tell the app to parse the body of the request
app.use(bodyParser.urlencoded({extended: true}));
app.use(bodyParser.json());
// tell the app to go through the middleware before proceeding to graphql
app.use(auth);
// setting the graphql route
app.use('/graphql', graphqlHttp({
schema: graphqlSchema,
rootValue: graphqlResolver,
graphiql: true,
formatError(err) {
if (!err.originalError) {
return err;
}
const data = err.originalError.data;
const message = err.message || 'An error occurred.';
const code = err.originalError.code || 500;
return { message: message, status: code, data: data };
}
})
);
app.use((error, req, res, next) => {
const status = error.statusCode || 500;
const message = error.message;
const data = error.data;
res.status(status).json({ message: message, data: data });
});
sequelize.sync({ force: true })
.then(() => {
app.listen(8080);
})
.catch(err => {
console.log(err);
});
the auth.js file (the middleware):
const jwt = require('jsonwebtoken');
module.exports = (req, res, next) => {
const authHeader = req.get('Authorization');
if (!authHeader) {
req.isAuth = false;
return next();
}
const token = authHeader.split(' ')[1];
let decodedToken;
try {
decodedToken = jwt.verify(token, 'somesupersecretsecret');
} catch (err) {
req.isAuth = false;
return next();
}
if (!decodedToken) {
req.isAuth = false;
return next();
}
req.userId = decodedToken.userId;
req.isAuth = true;
next();
};
I made my first API with NodeJs
this is what i get if i try to access to the resource from the url of the browser
I succed to access to posts with postman.
Now i tried to set a little call with a graphic site, but I wasn't able to fetch the datas
this is the call that i tried in a saga
export const fetchWrapper = async url => {
var request = new Request({
url: url,
method: "GET"
});
await fetch(request)
.then(res => res.json())
.then(
result => {
return result;
},
error => {
return error;
}
);
};
and this is the saga
export function* getPosts() {
const url = `http://localhost:8080/feed/posts`;
try {
const data = yield call(fetch(url), {method: 'GET'});
console.log('data',)
yield put(getPostsResponse({ data }));
} catch (e) {
console.log("error", e);
}
}
and these are the errors that i have in the console
UPDATE
As suggested in the comment this is my node code
controller/feed.js
exports.getPosts = (req, res, next) => {
res.json({
posts: [
{ id: 1, title: "Titolo 1", description: "descrizione 1" },
{ id: 2, title: "Titolo 2", description: "descrizione 2" },
{ id: 3, title: "Titolo 3", description: "descrizione 3" }
]
});
};
exports.createPosts = (req, res, next) => {
const title = req.body.title;
const description = req.body.description;
const ID = 1234;
res.status(201).json({
message: "success operation",
post: {
id: ID,
title: title,
description: description
}
});
};
route/feed.js
const express = require("express");
const router = express.Router();
const feedController = require("../controllers/feed");
router.get("/post", feedController.getPosts);
router.post("/post", feedController.createPosts);
module.exports = router;
app.js
const express = require('express');
const bodyParser = require("body-parser");
const feedRoute = require('./route/feed');
const app = express();
app.use(bodyParser.json()); //application json
app.use('/feed', feedRoute);
app.listen(8080);
UPDATE
useEffect(() => {
// getPosts();
fetch("http://localhost:8080/feed/post")
.then(resp => resp.json())
.then(data => console.log('data', data));
}, [getPosts]);
also tried this, but nothing, i receive the same error.
Expected behaviour:
I have to do a successful call to the localhost server.
Solution
As ivani suggested i just enabled the CORS, this is the code the code that I added to app.js. Not the best solution, but now i can see the response.
const allowedOrigins = ["http://localhost:3000", "http://localhost:8080"];
app.use(
cors({
origin: function(origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) === -1) {
var msg =
"The CORS policy for this site does not " +
"allow access from the specified Origin.";
return callback(new Error(msg), false);
}
return callback(null, true);
}
})
);
As ivani suggested i just enabled the CORS.
I added this to App.js of nodeJs
const allowedOrigins = ["http://localhost:3000","http://localhost:8080"];
app.use(
cors({
origin: function(origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) === -1) {
var msg =
"The CORS policy for this site does not " +
"allow access from the specified Origin.";
return callback(new Error(msg), false);
}
return callback(null, true);
}
})
);
Now i can reach the data
this is the entire App.js file
const express = require('express');
const bodyParser = require("body-parser");
const feedRoute = require('./route/feed');
const cors = require("cors");
const app = express();
const allowedOrigins = ["http://localhost:3000", "http://localhost:8080"];
app.use(
cors({
origin: function(origin, callback) {
if (!origin) return callback(null, true);
if (allowedOrigins.indexOf(origin) === -1) {
var msg =
"The CORS policy for this site does not " +
"allow access from the specified Origin.";
return callback(new Error(msg), false);
}
return callback(null, true);
}
})
);
app.use(bodyParser.json()); //application json
app.use('/feed', feedRoute);
app.listen(8080);
Try to add a proxy field to your package.json in your React folder:
"proxy": "http://localhost:8080"
Then, make your requests like that:
// this will also avoids CORS issues
const url = `/feed/posts`;
Request Example:
// Create a state `Array` (or Object) that will hold all your posts
const [posts, setPosts] = useState([])
useEffect(() => {
const getPosts = async () => {
try {
const response = await fetch('/feed/post');
const data = await response.json();
setPosts(data)
} catch(err) {
console.log(err); // failed to fetch
}
}
// Make the request
getPosts()
}, [/* no dependencies */])
return (
// JSX use 'posts' here
)
For me the solution provided by Legeo didn't work, but this more simple solution worked
const cors = require("cors")
app.use(cors())
or this modern
import cors from 'cors';
app.use(cors())
When i try to make a request to my server the client send two requests, the first with an empty body, and the second with the correct body
this is my server file
const express = require('express');
const app = express();
const server = require('http').createServer(app);
const io = require('socket.io')(server);
const cors = require('cors');
const bodyParser = require('body-parser');
const authMiddleware = require('./app/middlewares/auth.middleware');
const db = require('./config/db');
app.use(authMiddleware);
app.use(cors({ origin: '*' }));
app.use(bodyParser.json());
db.then(res => {
require('./app/routes')(app);
});
server.listen(3210, () => {
console.log('\x1b[0m', 'Backend escutando e enviando na porta 3210');
});
this is the route file
const userController = require('../controllers/user.controller');
module.exports = app => {
app.post('/sign-up', async (req, res) => {
try {
const signUpData = await userController.signUp(req.body);
res.status(200).json(signUpData.user);
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
app.post('/sign-in', async (req, res) => {
try {
const signInData = await userController.signIn(req.body);
res.header('x-auth-token', signInData.token);
res.status(200).json(signInData);
} catch (error) {
console.log(error);
res.status(400).json(error);
}
});
};
here is my axios configuration on my react project
import axios from 'axios';
export const apiUrl = 'http://localhost:3210';
export const api = axios.create({
baseURL: apiUrl,
headers: {
common: {
'Content-Type': 'application/json'
}
}
});
the function where i do the request
export const signIn = data => {
return api
.post(`/sign-in`, data)
.then(res => {
console.log(res);
})
.catch(err => {
console.log(err);
});
};
This error only occours when the request is made via client, when i
use postman everything works fine