Division of responsibilities (service and routing layers)

I'm looking to enhance my Node JS skills by improving the way I separate the service and router layers in my applications. I want to avoid code duplication, like in the case of the create method for a user scheme.

In my UserService.Js file, I have the following method:

function createUser(req, res, next) {

  let user = new User({
    userID: req.body.userID,
    userName: req.body.userName,
    password: req.body.password,
    isAdministrator: req.body.isAdministrator
  });
  user.save().then(function() {
    res.send(user);
  }).catch(err => {
    console.log(err);
  });

}

The code in UserRouter.Js connects this method:

router.post('/publicUser', userService.createUser)

Although it functions correctly, the separation of concerns could be improved. What's the best way to rewrite the create function using a callback function?

My revised version is as follows:

UserService.js  

function createUser() {

  let user = new User
  return user;
}

UserRoute.js    

router.post('/publicUser', function(req, res, next){
  let newUser = userService.createUser()
  newUser.userID = req.body.userID
  newUser.userName = req.body.userName
  newUser.password = req.body.password
  newUser.isAdministrator = req.body.isAdministrator
  newUser.save().then(function() {
        res.send(newUser);
      }).catch(err => {
        console.log(err);
      })})

This updated approach works well, but I wonder if there is a more elegant solution available?

Answer №1

Here is a sample code snippet to demonstrate implementation. Feel free to customize it based on your specific needs and requirements.

UserRouter.Js

// Import the necessary service
router.post('/publicUser', createUser)

async function createUser(req, res, next) {
    try {
        const response = await UserService.createUser(req.body);
        res.send(response); // Customize 'res' object according to your preferences before returning.
    } catch (error) {
        // Log the error
        res.status(500).send(''); // Customize 'res' object with error details and status code before returning.
    }
}

UserService.Js

async function createUser(body) {
    // Validate the body for any missing information and handle errors appropriately.
    let userModelData = UserModel.getUserInsertPayload(body);
    return UserRepository.save(userModelData);
}

UserRepository.js

// All database-related operations should be handled in this layer.
async function save(user) {
    // Perform any necessary modifications to the payload here.
    return User.save(user);
}

UserModel.js

// Import the User model and define the payload structure based on User requirements.
function getUserInsertPayload(body) {
    return new User({
        userID: req.body.userID,
        userName: req.body.userName,
        password: req.body.password,
        isAdministrator: req.body.isAdministrator
    });
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Unlimited digest loop in Angular.js caused by nested ng-repeat and filter

In my AngularJS project, I have developed a custom filter that categorizes elements by type and performs a search for multiple search terms across all attributes of devices. angular.module('abc').filter('searchFor', function(){ return ...

Tips for accessing an array you've constructed in the $onInit() function within Angular-Fullstack

I am currently working on an Angular fullstack project that utilizes Babel and Angular 1.5.0. The problem I am encountering is that I am trying to initialize an array (this.events = []) but unable to access this array in $onInit() where I need to populate ...

Performing calculations in JavaScript using data retrieved from a MySQL database in PHP

I am facing an issue where I need to retrieve data from a MySQL database, specifically the column "Ticketkosten". This involves fetching all the data and passing it to a JavaScript function for real-time calculations. The current setup includes hardcoding ...

Obtaining specific data from the forEach iteration, post-click event with JavaScript

Trying to access the value from a Tree-structured Array of Objects stored in Local Storage, https://i.sstatic.net/YJ1PI.png Created a function that retrieves values from local storage using forEach and displays them on the screen. https://i.sstatic.net/ ...

What is the best way to adjust the transparency of the document.body?

Is it possible to set the body of a website to have a low opacity while keeping a popup at full opacity to make it stand out? I attempted to specify the popup with opacity: 1 !important; but it didn't work as expected. Can you help me figure out how ...

Exploring the Realm of Javacript Template Literal Capabilities

Is it possible to define a variable inside a template literal and then utilize it within the same template? If this isn't feasible, it appears to be a significant feature that is lacking. const sample = tag` some random words, ${let myvar = 55} addit ...

Delay the execution of @mouseover in Vue: a guide to managing scope

Looking to implement an action only when the user has hovered over a div for at least 1 second. Here's how it's set up: <div @mouseover="trigger"></div> In the script section: data() { return { hovered: false } } m ...

Is it possible to retrieve JSON data and display only the entries with positive values in an HTML

I am working on a project that involves fetching JSON API data and displaying it in an HTML table, but only for values above 10. Below is the code snippet along with my JavaScript. I specifically want to exclude negative values and only display positive v ...

Implementing asynchronous file reading with module.exports in Node.js

Apologies in advance for what may seem like a basic question, but I'm delving into the inner workings of node and need help with a particular issue: I am trying to send an object or file from fs.readFile using require and module.exports. So far, this ...

Building a TypeScript function using a dictionary with function names and argument types

In possession of a dictionary { "function_name":"myFunc", "arguments":["a1","a2"] } A desire to create a function where the name matches that in the dictionary above (i.e myFunc ) with respective arg ...

Navigating to the most recent item within ng-repeat (AngularJS or JavaScript)

I am working on a feature where posts are displayed using ng-repeat in a div, and users can enter new posts in an input box. The posts are sorted so that the latest one appears at the bottom. After adding a new post, I want to automatically scroll down t ...

Utilizing global variables in Vue.js while working with the CLI template

How can I create a global variable in my Vue.js app that is accessible by all components and modifiable by any of them? I am currently utilizing the CLI template. Any recommendations on how to achieve this? Appreciate your assistance. Dhiaa Eddin Anabtaw ...

Loop through page.evaluate in Nodejs

Currently, I am attempting to utilize the for-of looping method in order to iterate through an array of URLs and apply them with the page.evaluate function from the puppeteer library. To simplify my process, I will share a snippet of my code (with a sing ...

Replicate the functionality of a backend API using AngularJS

Currently, I am in the midst of creating a GUI for an application that is still undergoing API development. Although I have a vision of how it will look, it lacks functionality as of now. Hence, I need to replicate its behavior until the API is fully funct ...

What is the best way to refresh a navigation bar after making an API request, such as when using Google Sign-In?

Struggling to grasp the hook concept in this particular scenario: The flow goes like this - the user logs in with Google, which updates the session state. Consequently, the visitorType state transitions from 'viewer' to 'buyside'... A ...

What could possibly be causing this peculiar behavior of an AJAX post request in Node.js Express by executing a GET request with the data just before the actual post request is

I'm facing an intriguing challenge. I have a form where I intend to implement ajax to perform a post request on the server. replyPrefix = "<div id='addCommentContainer'><form class='addCommentForm' name='addcomment&a ...

Transfer attributes, but have exclusions in React

At times, we all have a common practice of wrapping DOM elements in custom components. <CustomComponet id="abc" title="abc" nonDomProp="abc" ...andsoforth /> In this example, the custom component wraps a button with pr ...

Tally up every digit until they match the data attribute

I have a challenge with counting a few bars until they reach a specific value set in their data-line attribute. Below is the code I am currently using where I have tried to use setInterval to increment the counter, but I am unable to clear the interval whe ...

When using React and React Router v6, make sure to implement a 404 status code response for unmatched routes

When it comes to managing unmatched routes with React Router, I have a solid understanding: <Routes> {/* Public routes */} <Route exact path="/" element={<Home />} /> // Other routes... {/* Error routes */} ...

Tips for implementing orderBy and filter in ng-repeat when working with an object instead of an array

I am facing a data structure that looks like this: $scope.people = { "ID123": { name_de: "Andre", name_en: "Anrew", age: 30, description: "He is the father of xyz and . . .", . . . ...