npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

model-mapper

v1.2.5

Published

Utility for flattening models into view models

Downloads

31

Readme

model-mapper Build Status

You can use this tool to copy data from nested models into a flattened view model.

You tell the mapper how to create the view models by creating maps. This can be done with the createMap function. You can also createMapsFromDir and point the mapper at a directory with your maps. The actual mapping is done with the map function.

createMap(outputName, map)

outputName can be anything, this is simply the key used to reference the map later. It makes sense however, to name this as the type of object you expect to map to.

map is an object containing the configuration of your view model. Each property of this object will be in your resultant view model.

createMapsFromDir(directory)

directory is the full path to the directory you have your map files in. These files just need to export a map object containing the configuration for your view model. The name of the file (minus the .js) will be used as the outputName

The map config object

An example configuration file from the example folder in the project (ExampleViewModel.js):

var mapper = require('model-mapper');

module.exports.map = {
    number: '=',
    string: '=',
    date: '=',
    method: '=',
    object: '=',
    array: '=',
    nested: 'object.member',
    deepnest: 'a.b.c.d.e',
    func: function(example){
        return example.method();
    },
    mapping: function(example){
        return mapper.map('NestedViewModel', example.nested);
    }
};

An example input object for this configuration might be:

var Nested = {
    nestedMapping: 'nestedMapping'
};

var Example = {
    number: 5,
    string: 'string',
    date: new Date(2014, 1, 1),
    method: function(){
        return 'method';
    },
    object: {
        member: 'member'
    },
    array: ['array'],
    a: {
        b: {
            c: {
                d: {
                    e: 'nested'
                }
            }
        }
    }
};
Example.nested = Nested;

This object can then be mapped using map('ExampleViewModel', Example);. You can also use the same call to map an array of objects, by simply passing in the array of Example objects.

You can create mappings of your properties in 3 ways:

"=" specifies a direct mapping. The mapper will look for a property of the same name on the input object and copy the property directly

"some.property.list" indicates some nested property path in the input object

functions can be specfied as configuration properties and these will be executed by the mapper, with the current input object passed in to the function. This enables you to nest mappings as above in the example. It also allows you to add calculated fields to your resultant view models.

Asynchronous mapping functions

Added support for asynchronous mapping functions. A callback can now be optionally passed to map, causing the function to be treated asyncronously.

For example, using the following map definition containing an async function:

module.exports.map = {
    async: function(example, done){
        setTimeout(function(){
            if (example.error){
                done('ERROR');
            }
            else {
                done(null, 5); // The second parameter passed to the done callback will be the value of the async property
            }
        }, 200);
    }
}

Call the mapping function on an empty object:

mapper.map('AsyncExample', {}, function(err, result) {
    // Access result here
});

The callback follows the Node convention of error then result, and will contain an array of any errors generated during asynchronous calls. For example, any database accesses that resulted in errors will have the error propagated to this callback. If no callback is supplied to map, the call will be treated synchronously and the result will be returned as usual.

The signature of the async map function: map(outputName, input, [callback])

Constants

Added support for directly mapping constant values. You can now directly map values to your resultant objects. All values will map directly except for strings.

In the case of string constants, you must prefix them with '=' to prevent an attempted property mapping, unless you desire an empty string, in which case '' will work just fine.

Example constants object mappings:

module.exports.map = {
    number: 5,
    double: 4.1,
    string: '=whatever',  // The output for this property will be 'whatever'
    emptyString: '',
    array: ['array'],
    object: {
        property: 'copied'
    },
    nullValue: null,
    undefinedValue: undefined
};

If you want to map a function to your output, you can define a function that returns a function.

Aliasing maps

You can now alias the maps you add from a directory with the createMapsFromDir method. Simply export a string field called alias and this will be the name of your map instead of the filename. For example:

module.exports.alias = 'MyAlias';

module.exports.map = {
    placeholder: null
};

Metadata

You can now add metadata to your map definition files. Use this to include any arbitrary data you want to associate with your mappings.

You can set the metadata for a map by calling setMetadata(outputName, metadata) directly, or by exporting a metadata object in your map file. The metadata can then be accessed with getMetadata(outputName)

This feature is useful, for example, if you want to associate some database retrieval data with a view model. Eg. If using Mongoose, you can store the string of fields to be populated for that view model.

Auto Functions

You can configure model-mapper to automatically try and execute a function on a property. For example, in your server.js, if you added:

mapper.addAutoFunction('_id', 'toString');

This would cause the toString() method to be called on any properties found by the mapper called _id. This is notably useful for automatically converting Mongoose _ids to their string representation.