MARKAND Bhatt MARKAND Bhatt - 1 month ago 17
reST (reStructuredText) Question

how to create models in nodejs

I am a .net developer, trying my hands on nodejs web api development.

I was wondering that whether we can create models in nodejs same as we create in asp.net web api.

For example

public class BaseResponse
{
public bool Success { get; set; }

public string ErrorMessage { get; set; }

}

public class MovieResponse : BaseResponse
{
public int MovieId { get; set; }

public string MovieName { get; set; }
}


This is how we do it in c#.

How can i create such models in nodejs.

Any npm package available?

Answer

There's good news and there's bad news. The bad news is the concept of classes and inheritance as you know it from other languages is not supported. The good news, JavaScript attempted to do something along that idea (although it did a miserable job implementing it). Below is an example of the code you provided using JavaScript:

function BaseResponse(success, errorMessage) {
    this.success = success;
    this.errorMessage = errorMessage;
}

function MovieResponse(success, errorMessage, movieId, movieName) {
    BaseResponse.call(this, success, errorMessage);  // Call the base class's constructor (if necessary)

    this.movieId = movieId;
    this.movieName = movieName;
}

MovieResponse.prototype = Object.create(BaseResponse);
MovieResponse.prototype.constructor = MovieResponse;

/**
 * This is an example of an instance method.
 */
MovieResponse.prototype.instanceMethod = function(data) { /*...*/ };

/**
 * This is an example of a static method.  Notice the lack of prototype.
 */
MovieResponse.staticMethod = function(data) {/* ... */ };

// Instantiate a MovieResponse
var movieResInstance = new MovieResponse();

Mozilla has really good documentation on JavaScript and classes. In the code above, you are creating two functions BaseResponse and MovieResponse. Both of these functions act as constructors for an object with the appropriate "class" when you use the new keyword. You specify that MovieResponse inherits from BaseMovie with MovieResponse.prototype = [Object.create](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create)(BaseResponse). This effectively sets MovieResponse's prototype chain equal to BaseResponse's prototype chain. You'll notice that immediately after setting MovieResponse's prototype chain I have to set its constructor to point to MovieResponse. If I didn't do this, every time you tried to initialize a MovieResponse, JavaScript would try to instead instantiate a BaseResponse (I told you they did a horrible job).

The rest of the code should be relatively straightforward. You can create instance methods on your brand new, shiny class by defining them on the prototype chain. If you define a function on BaseResponse that is not defined on MovieResponse but call the function on an instance of MovieResponse, JavaScript will "crawl" the prototype chain until it finds the function. Static methods are defined directly on the constructor itself (another weird feature).

Notice there is no concept of types or access modifiers (public/private). There are runtime tricks that you can implement to enforce types, but it's usually unnecessary in JavaScript and more prone to errors and inflexibility than adding such checks may justify.

You can implement the concept of private and protected members of a class in a more straightforward method than types. Using Node's require(), and assuming you wanted a private function called privateMethod you could implement it as:

function privateMethod() { /* privateMethod definition */ }

// Definition for MovieResponse's constructor
function MovieResponse() { /*...*/ }

module.exports = MovieResponse;

I will add a somewhat required commentary that I do not agree with: it is unnecessary to use inheritance in JavaScript. JavaScript uses a notion coined "duck typing" (if it looks like a duck and sounds like a duck, its a duck). Since JavaScript is weakly typed, it doesn't care if the object is a BaseResponse or MovieResponse, you can call any method or try to access any field you want on it. The result is usually an error or erroneous/error-prone code. I mention this here because you may come across the notion and its supporters. Know that such programming is dangerous and results in just bad programming practices.