waterloo-mapper
v1.0.0
Published
Object to object mapper with no dependencies
Downloads
76
Readme
waterloo-mapper
waterloo-mapper is object to object mapper
Example usage
Source object:
var src = {
id: 1,
name: 'Ibrahim',
cars: [
{id:1, brand: 'Ferrari', model: '458'},
{id:2, brand: 'Lamborghini', model: 'Aventador'},
],
address:{
id: 1,
country: 'Bulgaria',
city: 'Razgrad',
postCode: '7200'
}
}
Destination object:
var dest = {
id: 0,
name: null,
cars: [],
address:{
id: 0,
country: null,
city: null,
postCode: null
}
}
When source and destination have the same type we simply can map with:
import { Mapper } from 'waterloo-mapper';
new Mapper().from(src).to(dest).map();
//Destination object will be exact copy of the source object
{
id: 1,
name: 'Ibrahim',
cars: [
{id:1, brand: 'Ferrari', model: '458'},
{id:2, brand: 'Lamborghini', model: 'Aventador'},
],
address:{
id: 1,
country: 'Bulgaria',
city: 'Razgrad',
postCode: '7200'
}
}
Actual mapping is triggered when we call .map()
Custom function mapping
Lets say we have fullAddress field at our destination object
var dest = {
id: 0,
name: null,
fullAddress // here we want to get all address fields as single line
address:{
id: 0,
...
}
}
import { Mapper } from 'waterloo-mapper';
//We can save the mapper instance and use it multiple times
//keeping the logic we applied for fullAddress
var mapper = new Mapper()
.for('fullAddress').use(src => `${src.address.country}, ${src.address.city}, ${src.address.postCode}`);
mapper.from(src).to(dest).map(); //Trigger the mapping
// Destination object after mapping will be:
{
id: 1,
name: 'Ibrahim',
fullAddress: 'Bulgaria, Razgrad, 7200'
...
}
Nested mapping
Lets say we want the fullAddress field to be inside the address object this time
var dest = {
id: 0,
...
address:{
id: 0,
fullAddress: null // now we moved fullAddress inside adress
...
}
}
import { Mapper } from 'waterloo-mapper';
// We create mapper for the address
// Here we will have the address object in 'use'
// and as second parameter we will receive the parent object
var addressMapper = new Mapper()
.for('fullAddress').use((addr, parent) => `${addr.country}, ${addr.city}, ${addr.postCode}`);
// Create mapper for the whole object and here we say for 'address' we want to use our 'addressMapper'
var mapper = new Mapper()
.for('address').use(addressMapper);
mapper.from(src).to(dest).map(); //Trigger the mapping
// Destination object after mapping will be:
{
id: 1,
name: 'Ibrahim'
...
address: {
id: 1,
...
fullAddress: 'Bulgaria, Razgrad, 7200'
},
}
Array mapping
If we dont set any 'use' array will be copied as it is
If we want a custom mapping for the array we can do like this:
var dest = {
id: 0,
...
cars: [],
...
}
import { Mapper } from 'waterloo-mapper';
// Lets say we want brand and model as single string
// Callback function passed to 'forAll' is called for each object in the array
// and the object from the current iterration is passed
var mapper = new Mapper()
.for('cars').forAll(car => { return {id: car.id, name: car.brand + ' ' + car.model}; });
// Alternatively we can use 'use' to achive the same functionality as shown above
// but 'forAll' is bit more clear and less verbose
/*
.for('cars').use(obj => obj.cars.map(car => {
return {id: car.id, name: car.brand + ' ' + car.model};
}));
*/
mapper.from(src).to(dest).map(); //Triggering the mapping
// Destination object after mapping will be:
{
id: 1,
...
cars: [
{id:1, name: 'Ferrari 458'},
{id:2, name: 'Lamborghini Aventador'},
],
...
}
After Map
var mapper = new Mapper()
.afterMap((src, dst) => {
// Called after mapping is finished
// we have access to source and destination objects
// Add any custom login here...
});
mapper.from(src).to(dest).map();