Skip to content

Instantly share code, notes, and snippets.

@mschmulen
Forked from anonymous/README.md
Last active August 23, 2022 22:42
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save mschmulen/6740321 to your computer and use it in GitHub Desktop.
Save mschmulen/6740321 to your computer and use it in GitHub Desktop.
LoopBack cheat sheet. git clone https://gist.github.com/6740321.git LoopBackCheatSheet

#LoopBack cheat sheet

##Recipies

LoopBack from api-example

Instantiate the sls-sample-app

slc example
cd sls-sample-app
slc install
slc run app.js

LoopBack from base

Create a custom LoopBack Node server

slc lb project loopback-server
cd loopback-server/
slc install
slc run .

Add a custom model type : product

slc lb model product

Run you server

slc run .

Debug your server

slc debug .

##Snippets

###Run with verbose output

DEBUG=* node app.js

##Adding a custom method to your LoopBack model

in this case I have a model called product, so I would add it to the /loopback-nodejs-server/modules/product/index.js before the module.exports = product call

// http://localhost:3000/products/taxInfo
product.currentTax = function(fn) {
    fn( null, tax );
}

loopback.remoteMethod(
  product.currentTax,
  {
    returns: {arg: 'currentTax', type: 'object'},
    http: {path: '/taxInfo', verb: 'get'}
  }
);

##Exploring LoopBack Verify the server is running localhost:3000/ API explorer http://localhost:3000/explorer/ Routes Inventory http://localhost:3000/routes LoopBack Docs http://docs.strongloop.com/loopback#modelfindfilter-callback

Test the endpoint for the product model type: verif '[ ]' empty set localhost:3000/products

open http://localhost:3000/products

Add some test data of type product

//add some test data with curl to the 'product' model type
curl -X POST -H "Content-Type:application/json" -d '{"name": "Product A", "inventory": 11, "UPC": "127890"}' http://localhost:3000/products;
curl -X POST -H "Content-Type:application/json" -d '{"name": "Product B", "inventory": 22, "UPC": "127891"}' http://localhost:3000/products;
curl -X POST -H "Content-Type:application/json" -d '{"name": "Product C", "inventory": 33, "UPC": "127892"}' http://localhost:3000/products;
curl -X POST -H "Content-Type:application/json" -d '{"name": "Product D", "inventory": 44, "UPC": "123893"}' http://localhost:3000/products

Test the endpoint for the product model type: and verify newly added product instances localhost:3000/products

LoopBack from base to sailboat app

data Source : http://bluewaterboats.org/valiant-40/

Start interactive mode

slc model sailboat -i

Define the schema

"designer" "builder"  "loa"  "lwl"  "beam"	"draft"	"ballast"	"displacement"	"sailarea"	

Add some default data to the repo

curl -X POST -H "Content-Type:application/json" -d '{"designer": "Robert H. Perry","builder": "Valiant Yachts","loa": "39’ 11″ (12.16 m.)","lwl": " 34’ 0″ (10.36 m.)","beam": "12’ 4″ (3.76 m.)","draft": "6’ 0″ (1.83 m.)","ballast": "7,700 lbs. (3,493 kg.)","displacement": "22,500 lbs. (10,206 kg.)","sailarea": "772 sq. ft. (71.7 sq. m.)" }' http://localhost:3000/sailboats;

curl -X POST -H "Content-Type:application/json" -d '{"designer": "Robert H. Perry","builder": "Valiant Yachts","loa": "37′ 0″","lwl": "31′ 7″","beam": "11′ 5″","draft": "5′ 9″","ballast": " 6,600 lbs","displacement": "17,000 lbs","sailarea": "667 sqft" }' http://localhost:3000/sailboats;

curl -X POST -H "Content-Type:application/json" -d '{"designer": "Robert H. Perry","builder": "Valiant Yachts","loa": "37′ 0″","lwl": "31′ 7″","beam": "11′ 5″","draft": "5′ 9″","ballast": " 6,600 lbs","displacement": "17,000 lbs","sailarea": "667 sqft" }' http://localhost:3000/sailboats;

curl -X POST -H "Content-Type:application/json" -d '{"designer": "Robert H. Perry","builder": "Valiant Yachts","loa": "37′ 0″","lwl": "31′ 7″","beam": "11′ 5″","draft": "5′ 9″","ballast": " 6,600 lbs","displacement": "17,000 lbs","sailarea": "667 sqft" }' http://localhost:3000/sailboats
  • template
curl -X POST -H "Content-Type:application/json" -d '{"designer": "","builder": "","loa": "","lwl": "","beam": "","draft": "","ballast": "","displacement": "","sailarea": "" }' http://localhost:3000/sailboats

Verify the data from the browser localhost:/3000/sailboats;

optional - from base

add docs: insert app.docs({basePath: 'http://localhost:3000'});

add the API Browser : http://localhost:3000/explorer/#!/sailboats/sail_find_get_4

Mobile Application Integration from sample

iOS App

iOS Sample

Mobile Application Integration from base

SDK install path : /usr/local/share/strongloop-node/strongloop/sdks

open /usr/local/share/strongloop-node/strongloop/sdks/

X.h #import <LoopBack/LoopBack.h>

LoopBack from preconfigured mobile app and loopback-node-server

git clone mobile-solution
  • (void) findProductLowestInventory {

    //Find the Product with the Product With the Lowest Inventory

    // Docs reference: // http://docs.strongloop.com/loopback/#example-request-4

    // HTTP REST Call: // http://localhost:3000/products?filter%5Blimit%5D=2

    void (^staticMethodErrorBlock)(NSError *) = ^(NSError *error) { NSLog( @"Error %@", error.description); [AppDelegate showGuideMessage: @"No Server Found"]; };//end selfFailblock

    // Define the load success block for the LBModelPrototype allWithSuccess message void (^staticMethodSuccessBlock)() = ^(id result) { NSLog(@"Success on Static Method result: %@", result);

      LBModel *model = (LBModel *)[result objectAtIndex:0];
      self.labelMethod1.text = [[NSString alloc] initWithFormat:@"%@ - %@",
                             [model objectForKeyedSubscript:@"name"] ,
                             (int)[model objectForKeyedSubscript:@"inventory"] ];
    

    };//end staticMethodSuccessBlock

    LBModelPrototype *objectProto = [ [AppDelegate adapter] prototypeWithName:@"products"];

    [[ [AppDelegate adapter] contract] addItem:[SLRESTContractItem itemWithPattern:@"/products" verb:@"GET"] forMethod:@"products.filter"];

    //Product with lowest inventory // http://localhost:3000/products?filter[order]=inventory%20ASC&filter[limit]=1': The highest inventory products [objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[order]":@"inventory ASC",@"filter[limit]":@1} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

}//end findPoductLowestInventory

  • (void) findProductLowestPrice {

    //Find the Product with the Product With the Lowest Inventory

    // Docs reference: // http://docs.strongloop.com/loopback/#example-request-4

    // HTTP REST Call: // http://localhost:3000/products?filter%5Blimit%5D=2

    void (^staticMethodErrorBlock)(NSError *) = ^(NSError *error) { NSLog( @"Error %@", error.description); [AppDelegate showGuideMessage: @"No Server Found"]; };//end selfFailblock

    // Define the load success block for the LBModelPrototype allWithSuccess message void (^staticMethodSuccessBlock)() = ^(id result) { NSLog(@"Success on Static Method result: %@", result);

      LBModel *model = (LBModel *)[result objectAtIndex:0];
      self.labelMethod2.text = [[NSString alloc] initWithFormat:@"%@ - %@",
                                [model objectForKeyedSubscript:@"name"],
                            [model objectForKeyedSubscript:@"price"] ];
    

    };//end staticMethodSuccessBlock

    LBModelPrototype *objectProto = [ [AppDelegate adapter] prototypeWithName:@"products"];

    [[ [AppDelegate adapter] contract] addItem:[SLRESTContractItem itemWithPattern:@"/products" verb:@"GET"] forMethod:@"products.filter"];

    //Product with lowest inventory // http://localhost:3000/products?filter[order]=inventory%20ASC&filter[limit]=1': The highest inventory products [objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[order]":@"price ASC",@"filter[limit]":@1} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

}//end findProductHighest

//Filter Limit 2 http://localhost:3000/products?filter%5Blimit%5D=2
//[objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[limit]":@2} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

//Filter Pagination 2 http://localhost:3000/products?filter[limit]=2&filter[offset]=5
// TODO [objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[limit]=2&filter[offset]=5":@2} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

//Products with name Product A http://localhost:3000/products?filter[where][name]='Product A':
// TODO [objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[where][name]":@"Product A"} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

// Product with highest inventory
// http://localhost:3000/products?filter[order]=inventory%20DESC&filter[limit]=1': The highest inventory products
//[objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[order]=inventory&DESC&filter[limit]":@1} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];


//Product sorted Ascending ASC  Descending DESC
// http://localhost:3000/products?filter[order]=inventory%20ASC&filter[limit]=1': The highest inventory products
//[objectProto invokeStaticMethod:@"filter" parameters:@{ @"filter[order]":@"inventory DESC"} success:staticMethodSuccessBlock failure:staticMethodErrorBlock];

//'/weapons?filter[fields][name]=1&filter[fields][effectiveRange]=1': Only name and effective ranges
//'/weapons?filter[where][effectiveRange][gt]=900&filter[limit]=3': The top 3 weapons with a range over 900 meters
//'/locations': Locations
//'/locations?filter[where][geo][near]=153.536,-28.1&filter[limit]=3': The 3 closest locations to a given geo point

/*
 [[[AppDelegate adapter] contract] addItem:[SLRESTContractItem itemWithPattern:@"/location/nearby" verb:@"GET"] forMethod:@"locations.getNearestFew"];
 [LocationProto invokeStaticMethod:@"getNearestFew" parameters:@{
 @"here": @{
 @"lat": 37.587409,
 @"lng": -122.338225
 }
 } success:staticMethodSuccessBlock failure:staticMethodErrorBlock];
 */

-( void) customMethod1 {

// Define the load error functional block
void (^staticMethodErrorBlock)(NSError *) = ^(NSError *error) {
    NSLog( @"Error %@", error.description);
    [AppDelegate showGuideMessage: @"No Server Found"];
};//end selfFailblock

// Define the load success block for the LBModelPrototype allWithSuccess message
void (^staticMethodSuccessBlock)() = ^(id result) {
    NSLog(@"Success on Static Method result: %@", result);
    
    self.labelMethod1.text = @"Response 1";
    
};//end staticMethodSuccessBlock

//Get a local representation of the 'cars' model type
LBModelPrototype *objectB = [ [AppDelegate adapter] prototypeWithName:@"cars"];
[[ [AppDelegate adapter]  contract] addItem:[SLRESTContractItem itemWithPattern:@"/cars/custommethod1" verb:@"GET"] forMethod:@"cars.custommethod1"];

// Invoke the invokeStaticMethod message for the 'cars' LBModelPrototype
// Equivalent http JSON endpoint request : http://localhost:3000/cars/custommethod1
[objectB invokeStaticMethod:@"custommethod1" parameters:@{} success:staticMethodSuccessBlock failure:staticMethodErrorBlock ];

}//end CustomMethod1

-( void) customMethod2 { // Define the load error functional block void (^staticMethodErrorBlock)(NSError *) = ^(NSError *error) { NSLog( @"Error %@", error.description); [AppDelegate showGuideMessage: @"No Server Found"]; };//end selfFailblock

// Define the load success block for the LBModelPrototype allWithSuccess message
void (^staticMethodSuccessBlock)() = ^(id result) {
    NSLog(@"Success on Static Method result: %@", result);
    
    self.labelMethod2.text = @"Response 2";
    
};//end staticMethodSuccessBlock

//Get a local representation of the 'cars' model type
LBModelPrototype *objectB = [ [AppDelegate adapter] prototypeWithName:@"cars"];
[[ [AppDelegate adapter]  contract] addItem:[SLRESTContractItem itemWithPattern:@"/cars/custommethod2" verb:@"GET"] forMethod:@"cars.custommethod2"];

// Invoke the invokeStaticMethod message for the 'cars' LBModelPrototype
// Equivalent http JSON endpoint request : http://localhost:3000/cars/custommethod2?arg1=yack&arg2=123
[objectB invokeStaticMethod:@"custommethod2" parameters:@{@"arg1":@"yack" , @"arg2":@123} success:staticMethodSuccessBlock failure:staticMethodErrorBlock ];

}//end CustomMethod2

  • (void)customMethod3 { // ++++++++++++++++++++++++++++++++++++ // Uncomment the comment block below to call a custom method on the server // ++++++++++++++++++++++++++++++++++++

    // Define the load error functional block void (^staticMethodErrorBlock)(NSError *) = ^(NSError *error) { NSLog( @"Error %@", error.description); [AppDelegate showGuideMessage: @"No Server Found"]; };//end selfFailblock

    // Define the load success block for the LBModelPrototype allWithSuccess message void (^staticMethodSuccessBlock)() = ^(id result) { NSLog(@"Success on Static Method result: %@", result); };//end staticMethodSuccessBlock

    //Get a local representation of the 'cars' model type LBModelPrototype *objectB = [ [AppDelegate adapter] prototypeWithName:@"cars"]; [[ [AppDelegate adapter] contract] addItem:[SLRESTContractItem itemWithPattern:@"/cars/custommethod3" verb:@"GET"] forMethod:@"cars.custommethod3"];

    // Invoke the invokeStaticMethod message for the 'cars' LBModelPrototype // Equivalent http JSON endpoint request : http://localhost:3000/cars/custommethod3?arg1=yack&arg2=123 [objectB invokeStaticMethod:@"custommethod3" parameters:@{@"arg1":@"yack" , @"arg2":@123} success:staticMethodSuccessBlock failure:staticMethodErrorBlock ];

}//end customMethod3

<!DOCTYPE html>
<meta charset="utf-8">
<body>
<script src="http://d3js.org/d3.v2.min.js?2.9.7"></script>
<script>
var width = 960,
height = 200;
var nodes = d3.range(200).map(function() { return {radius: Math.random() * 12 + 4}; }),
root = nodes[0],
color = d3.scale.category10();
root.radius = 0;
root.fixed = true;
var force = d3.layout.force()
.gravity(0.05)
.charge(function(d, i) { return i ? 0 : -2000; })
.nodes(nodes)
.size([width, height]);
force.start();
var svg = d3.select("body").append("svg:svg")
.attr("width", width)
.attr("height", height);
svg.selectAll("circle")
.data(nodes.slice(1))
.enter().append("circle")
.attr("r", function(d) { return d.radius; })
.style("fill", function(d, i) { return color(i % 3); });
force.on("tick", function(e) {
var q = d3.geom.quadtree(nodes),
i = 0,
n = nodes.length;
while (++i < n) q.visit(collide(nodes[i]));
svg.selectAll("circle")
.attr("cx", function(d) { return d.x; })
.attr("cy", function(d) { return d.y; });
});
svg.on("mousemove", function() {
var p1 = d3.mouse(this);
root.px = p1[0];
root.py = p1[1];
force.resume();
});
function collide(node) {
var r = node.radius + 16,
nx1 = node.x - r,
nx2 = node.x + r,
ny1 = node.y - r,
ny2 = node.y + r;
return function(quad, x1, y1, x2, y2) {
if (quad.point && (quad.point !== node)) {
var x = node.x - quad.point.x,
y = node.y - quad.point.y,
l = Math.sqrt(x * x + y * y),
r = node.radius + quad.point.radius;
if (l < r) {
l = (l - r) / l * .5;
node.x -= x *= l;
node.y -= y *= l;
quad.point.x += x;
quad.point.y += y;
}
}
return x1 > nx2 || x2 < nx1 || y1 > ny2 || y2 < ny1;
};
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment