I am very new to AWS Lambda and Node.js, so apologies for the elementary question. I have two JS files in my Lambda project's root directory:
index.js
engageMessage(); //For testing purposes - throws error
exports.handler = async (event) => {
// TODO implement
const response = {
statusCode: 200,
body: JSON.stringify('This is index'),
};
return response;
};
messenger.js
function engageMessage() {
console.log("Messenger, checking in!");
};
How do I call engageMessage() from my index.js file? Each time I try, I get a "TypeError: engageMessage is not a function" message, and am unsure of how to properly reference/import/require messenger.js.
In messenger.js you need to export your function
module.exports = { engageMessage }
Then require it in your index.js
const { engageMessage } = require("./messenger.js")
I want to create an endpoint where others can post the data and then I can use it for further operations. I am using lambda and serverless framework for deployment. It is working fine in my local but each time I deploy it gives a 404 not foundError.(There are no issues in deployment).I get the following message in insomnia when testing the API-
Cannot POST /test/update
(test is my basePath)
I have cross-verified the domains and they are exactly the same as the ones present in serverless.yml file. Currently, I have the following code for the post request-
const express = require('express')
const eApp = express()
eApp.post('/update', async (req, res) => {
try {
// console.log('post req is:', req)
console.log('body', JSON.stringify(req.body))
res.sendStatus(200)
}
catch (e) {
console.log('error in post request is:',e)
res.sendStatus(200)
}
})
exports.eApp = eApp
const handler = serverless(eApp)
module.exports.handler = async (event, context) => {
context.callbackWaitsForEmptyEventLoop = false
const result = await handler(event, context)
return result
}
(The above code is present in index.js in routes folder).
The lambda function present in serverless.yml file is as following-
updateEndPoint:
handler: routes/index.handler
events:
- http:
path: /update
method: post
cors: true
I am also not getting any error in cloudwatch logs and can't find the root cause of the issue. Any help would be appreciated. Thanks in advance!!
EDIT- It is working with the domain address mentioned in lambda in aws (the one automatically assigned by aws) but not working with the domain address I have given in the serverless.yml file. Any fixes for this??
I am trying to implement this code in my Node/Express server.
https://www.npmjs.com/package/#google-cloud/language?activeTab=readme
async function quickstart() {
// Imports the Google Cloud client library
const language = require('#google-cloud/language');
// Instantiates a client
const client = new language.LanguageServiceClient();
// The text to analyze
const text = 'Hello, world!';
const document = {
content: text,
type: 'PLAIN_TEXT',
};
// Detects the sentiment of the text
const [result] = await client.analyzeSentiment({document: document});
const sentiment = result.documentSentiment;
console.log(`Text: ${text}`);
console.log(`Sentiment score: ${sentiment.score}`);
console.log(`Sentiment magnitude: ${sentiment.magnitude}`);
}
The above code I guess cannot be on the frontend react side. So I tried to use it in my app.js file reference it from a GET request, but the server won't compile because it says require doesn't exits.
app.get('/sentiment', async (req, res) => {
res.header('Access-Control-Allow-Origin', '*');
console.log('sentiment was called'.green.inverse);
var results = quickstart(req.params);
res.send(results);
});
Not sure how to resolve require or if even implementing this quickstart correctly?
I am running a node express server on Amazon ec2 instance. I can connect to the website on my local machine from within the browser, and can view pages with only local files, but when accessing a page that makes an external HTTP request, it just hangs. I figure it has something to do with my inbound or outbound rules are prohibiting it somehow, but don't know enough about networking to solve it on my own.
These are the functions that are failing behind the scenes:
const axios = require('axios').default;
const freelancer = axios.create({
baseURL: 'https://www.freelancer.com/api/',
headers: {
'freelancer-oauth-v1': process.env.FREELANCER_TOKEN
}
});
/* Get User By Id */
async function getUserById(user_id) {
const result = await freelancer.get(`/users/0.1/users/${user_id}/`)
return result.data.result;
}
const GitHub = require('github-api');
const gh = new GitHub({
username: process.env.GHUSER,
password: process.env.GHPASS
});
const getRepos = async function () {
const user = await gh.getUser();
return new Promise(async (resolve, reject) => {
await user.listStarredRepos(function (err, repos) {
if (err) reject(err);
resolve(repos);
});
});
}
My routers look like this:
var express = require('express');
var router = express.Router();
const freelancer = require('../service/Freelancer');
/* GET home page. */
router.get('/', async (req, res, next) => {
const reviews = await freelancer.getMyReviews();
const self = await freelancer.getSelfData();
res.render('contact', {
header: 'Check out all my reviews!',
lead: '',
paragraphtext: 'Your review could be next on this list!',
reviews,
self
});
});
Based on the comments.
The issue was caused by using HTTP for www.github.com. The solution was to use HTTPS.
My app (using vue) allows users to upload files with some info about the data to my node backend. When the user submits the form, this function is triggered:
methods: {
buttonOK () {
const formData = new FormData()
formData.append('name', this.detailFirm.name)
formData.append('description', this.detailFirm.description)
formData.append('version', this.detailFirm.version)
formData.append('date', this.detailFirm.date)
formData.append('file', this.file)
for (var [key, value] of formData.entries()) {
console.log(key, value)
}
let headers = {
'Content-Type': 'multipart/form-data',
'Accept': 'multipart/form-data'
}
this.$http.put('/firmware', formData, {headers: headers})
this.visible = false
}
The log statement shows everything that it ought to, and when this request is made, the network tab in the chrome dev tools shows the post data going through, and it has all the values it should:
name: test
description: test
version: 1
date: 0555-05-05
file: (binary)
My multer middleware looks like this:
const multer = require('multer')
const mult = multer({
dest: '/firmware'
})
module.exports = function (req, res, next) {
/* --Convert multipart/form-data to useable format within express-- */
if (req.path === '/firmware') {
mult.single('file')
console.log('MULTER MIDDLEWARE')
}
next()
}
The log statement there works, leading me to believe that multer is working.
I can't seem to access this information in back end though. Here I have tried both file and formData as the file name in mult.single('').
Here is my controller function:
let firmware = {
name: req.body.name,
version: req.body.version,
description: req.body.description,
date: req.body.date,
file: req.body.file
}
firmwareRepo.create(firmware, (err, create) => {
.............
I've read some other questions, and have made a few adjustments, but I always get an empty object when I log req.body in the controller. Please advise.
https://github.com/expressjs/multer#diskstorage
Note that req.body might not have been fully populated yet. It depends on the order that the client transmits fields and files to the server.
EDIT:
Firstly, I remember I had one problem on the frontend (React), by adding headers, which are not needed (somehow by adding formdata headers u **** up everything), here is the example:
data append stuff goes here
const data = new FormData()
data.append('id', values.id)
......
return async (dispatch) => {
const respond = await fetch('/api/postdata', {
method: 'post',
headers: {
//SEE? THIS IS EMPTY
},
body: data
})
// send form to backend
dispatch(dataSend())
}
}
Second issue could be on the backend. The thing is, that you can't just simply access file info through the req.body. You need to access it through the req.file
.post('/api/post', (req, res, next)=> {
const photo = {}
const newData = {}
uploadData(req, res, (err) => {
if(err){
console.log('error')
}
else {
Object.assign(photo, {file: req.file})
Object.assign(newData, {newData: req.body})
Then pass the photo to where you want to do something with it
const addDataController = new AddDataController(req, res, next, newAdvertData, photo)
addAdvertController.postAdvert()
}
})
Basically what I did is I separated regular data with file, and passed them further to combine and conclude the form. Sorry if this won't help, you're very close anyways!
I don't know why this worked, but everything started functioning as it should when I stopped using multer as an imported middleware, like this:
module.exports = function (req, res, next) {
/* --Convert multipart/form-data to useable format within express-- */
if (req.path === '/firmware') {
mult.single('formData')
console.log('MULTER MIDDLEWARE')
}
next()
}
and instead applied it directly to the route function, like this:
router.put('/firmware', upload.single('formData'), firmware.create) // doesn't work as standalone middleware
If anyone knows why that would be the case, please let me know.