I have two file alarm.js and notifications.js. In alarm.js I need to call a method called sendPush from notifications.js.
What I've tried :
Exporting the function from notifications.js:
module.exports.sendPush = function(params){
console.log("sendPush from notifcations.js called");
console.log(params);
}
Importing it in alarm.js and use it :
let helperNotif = require('./notifications')
router.post("/", async (req, res) => {
const params = {
param1: 'a',
param2: 'b'
}
helperNotif.sendPush(params)
});
The problem:
I keep getting the error saying helperNotif.sendPush is not a function
The question :
How can I call this notification.js sendPush function from my alarm.js file ?
[EDIT] maybe I should add that in notifications.js I have some router.get and router.post and at the end module.exports = router;
If your notifications.js ends with module.exports = router, that will overwrite your module.exports.sendPush = .... If you want to export both the router and the sendPush, you can write
function sendPush(params){
console.log("sendPush from notifcations.js called");
console.log(params);
}
...
module.exports = {router, sendPush};
To import the router elsewhere, you must then write
const {router} = require("./notifications.js");
Related
I have defined a function service in one of the file
import Category from '../models/Category.js';
export const AllCategories = () => {
console.log('hit');
const cursor = Category.find({});
console.log(cursor);
return cursor
}
export default {AllCategories}
I am importing this in the controller file
import express from 'express';
import categoryService from '../services/categories.js'
const router = express.Router();
export const getCategories = async(req,res) => {
try {
const categoriesInfo = categoryService.AllCategories
res.status(200).json(categoriesInfo)
} catch (error) {
res.status(404).json({ message: error.message });
}
}
export default router;
But the issue is that AllCategories is not getting run, what is wrong here
I also tried adding async/await
import Category from '../models/Category.js';
export const AllCategories = async () => {
try {
console.log("hit");
const cursor = await Category.find({});
console.log(cursor);
return cursor
} catch (error) {
return error
}
}
export default {AllCategories}
But still no luck
You're not calling the function, this saves it in the variable categoriesInfo:
const categoriesInfo = categoryService.AllCategories
To get its return value:
const categoriesInfo = await categoryService.AllCategories();
Note: I think you need to make it async if you're doing a db transaction so keep the second version and test it.
You can't use the ES module or ESM syntax by default in node.js. You either have to use CommonJS syntax or you have to do 1 of the following.
Change the file extension from .js to .mjs
Add to the nearest package.json file a field called type with a value of module
What is different between module.exports = testMethod ; and module.exports = { testMethod } ; Because when I am using module.exports = testMethod ; it is throwing error as below.
Error: Route.get() requires a callback function but got a [object Undefined]
But I am okay with module.exports = { testMethod } ;
Whole codes are
const testMethod = asyncErrorWrapper(async (req, res, next) => {
const information = req.body;
const question = await Question.create({
title: information.title,
content: information.content,
user: req.user.id,
});
res.status(200).json({
success: true,
data: question,
});
});
module.exports = { testMethod };
From VSCode, change between the ES5 or ES6 version to Js can take you on a bad way.
So, be carreful, i have the same problem recently, and after refactoring by use on ES6 module.exports = router to the end of some Js file (Node project using express) it was done.
Strange for me, on Cloud9 on Aws i have no problems.
Both are worked to export your module to outside function. But when you are using any callback function with
module.exports = somectrl
then it will fail but
module.exports = { somectrl }
because when you create an object, it actually instanciate it but when you pass a ref function/ const function name then it will behave as a existing function which does not work right.
you can do something like this to work,
module.exports = somectrl()
or
module.exports = new somectrl()
So I have written code to handle this, essentially it looks for any placeholder.controller.ts file in my project and uses the exported array of controllers to add routing. Controllers have to be default exported in an array with a specific format.
the format looks like this:
const controller1 = {
endpoint: '/hello/world',
method: 'get',
controller: () => console.log('hello world!'),
}
export default [
controller1
];
The routing code that handles all of this, exists in a routes.ts file and looks like this:
import glob from 'glob';
import path from 'path';
import { Router } from 'express';
import { toArray } from '../lib/utilities/generic-utilities';
import { isRouteType, isArrayWithContent } from '../lib/utilities/type-checking';
import { skip } from '../lib/middleware/generic-middleware';
import { Route } from '../meta/#types/common-types';
import { secureRoutesConstant, extension } from './settings';
import secureRoute from '../lib/middleware/secure-route';
const router: any = Router({ mergeParams: true });
// relative path from routes file to controllers folder.
const controllersPath = '../http/controllers/';
const addRouteToRouter = (route: Route, filename: string) => {
const acceptableRoute: object | boolean = isRouteType(route);
const message: string = `issue with route while exporting a controller in file ${filename}\nroute supplied was:`;
if (!acceptableRoute) console.log(message, route);
if (!acceptableRoute) return;
const { endpoint, controller, method, isSecure = secureRoutesConstant } = route;
const { middlewareBefore = [], middlewareAfter = [] } = route;
const makeRouteSecure: Function = isSecure ? secureRoute : skip;
const middlewareBeforeArr: Function[] = toArray(middlewareBefore);
const middlewareAfterArr: Function[] = toArray(middlewareAfter);
const routeArguments: Function[] = [
...middlewareBeforeArr,
makeRouteSecure,
controller,
...middlewareAfterArr,
];
router.route(endpoint)[method](...routeArguments);
};
const addToRouterForEach = (allRoutes: Route[], filename: string) =>
allRoutes.forEach((route: Route) => addRouteToRouter(route, filename));
glob
.sync('**/*.ts', { cwd: path.join(`${__dirname}/`, controllersPath) })
.filter((filename: string) => filename.split('.').includes('controller'))
.map((filename: string) => ({ defaultsObj: require(`${controllersPath}${filename}`), filename }))
.filter(({ defaultsObj }) => isArrayWithContent(defaultsObj.default))
.forEach(({ defaultsObj, filename }) => addToRouterForEach(defaultsObj.default, filename));
export default router;
And is simply imported into app.ts and used like this:
app.use('/api', router)
Essentially this means I have no routing code as it's all handled for me, I only have to write my services, controllers and models.
Is there any performance or security issues with doing things like this, or with the code itself?
Is there any performance or security issues with doing things like this, or with the code itself?
Performance
No. The auto code will only run on boot and even if it takes a second its not a cost you are paying on individual client request route handling.
Security
The code architecture is secure by itself and does not increase your risk of vulnerabilites.
I am creating my first project in Node and someone told me that it is a good practise to create a .js file having all the common and frequently used function
For example suppose I want to query something to my mongoose, to fetch data or update data, I should create a js file from where all the operations should happen.
Consider I have a Mongoose Schema which looks like this
const mongoose = require('mongoose')
const userSchema = new mongoose.Schema({
fullName: String,
email: String,
passowrd: String,
image: String
})
module.exports = mongoose.model('User', userSchema);
To perform a function such as checking if the user exsist in the Db, I created a .js file in my helper function folder known as my_db_query.js where I imported my mongoose schema and made many common function which interact with my schema (or other schemas in my mongoose)
Const user = requeire(./../model/user.js)
//other schema
function findByEmail (email) {
return User.findOne({email: email}).then((currentUser) => {
return currentUser
}
function updateUser (updatedData) {
//to update user
}
function deleteUser (user) {
//to delete a user
}
Now, Suppose I have a folder routes where I need to use them.
route.delete("/:delete", isAdmin, (req, res) => {
})
route.get("/:id", (req, res) => {
})
route.put(/:id, isAdmin, (req, res) => {
})
Question: How can I able to export all function at once and how can I import and use them in my routes file
How can I able to export all function at once ?
module.exports = { findByEmail, updateUser, deleteUser };
Just export an object containing the functions.
and how can I import and use them in my routes file ?
You could destructure the exported object:
const { findByEmail, updateUser, deleteUser } = require("./my_db_query");
findByEmail("test#example.com").then(/*...*/).catch(/*...*/);
In your .js file, you can export whatever functions you would like to use in other parts of your code base. The below is an example of what should go at the bottom of your .js file. It will export the 3 functions you defined.
module.exports = {
findByEmail,
updateUser,
deleteUser
}
In your routes file you can then import the file/functions. At the top of your routes file you need to include the below. In the below example, commonMethods.js is the file name of the .js file and all of the files are located in the same directory.
const commonMethods = require('./commonMethods.js')
You can then use any of the common methods like this: commonMethods.updateUser(updatedData)
Export all function at once:
I prefer to encapsulate everything inside an object.
const index = {};
index.findByEmail = function() { ... }
index. updateUser = function() { ... }
index. deleteUser = function() { ... }
module.export = index;
Import 1
const lib = require('./lib.js');
Import 2
const {findByEmail, updateUser , deleteUser } = required('./lib.js');
I'm trying to check if a user is authenticated. I do this by checking some record in asyncStorage, I have the following code
App.js
let AuthService = require('./app/layouts/AuthService/AuthService.js');
export default class App extends React.Component {
componentDidMount() {
AuthService.getAuthInfo((err, authInfo) => {
this.setState({
checkingAuth: false,
isLoggedIn: authInfo != null
})
});
}
}
Auth.js
'use strict';
let AsyncStorage = require('react-native').AsyncStorage;
let _ = require('lodash');
const authKey = 'auth';
const userKey = 'user';
class AuthService {
getAuthInfo(cb){
AsyncStorage.multiGet([authKey, userKey], (err, val)=> {
if(err){
return cb(err);
}
if(!val){
return cb();
}
let zippedObj = _.zipObject(val);
if(!zippedObj[authKey]){
return cb();
}
let authInfo = {
header: {
Authorization: 'Basic ' + zippedObj[authKey]
},
user: JSON.parse(zippedObj[userKey])
}
return cb(null, authInfo);
});
}
}
module.exports = new AuthService();
In app.js, I'm trying to use this function from Auth.js, but I get no response from the fuction, I get console logs from getAuthInfo before I get into the AsyncStorage function. Im pretty new to react-native and ES6, and I think is a promise or async problem but I cant make it work. In app.js im redering a ActivityIndicator so I dont block the UI with checkingAuth and isLoggedIn.
I tried to use some .then in app.js with no results.
First of all, you return your callback function instead of calling it. Try to call it by removing return like this : cb(null, authInfo);.