Giter VIP home page Giter VIP logo

loopback-example-offline-sync's Introduction

loopback-example-offline-sync

⚠️ This LoopBack 3 example project is no longer maintained. Please refer to LoopBack 4 Examples instead. ⚠️

An example running LoopBack in the browser and server, demonstrating the following features:

  • offline data access and synchronization
  • routes shared between the AngularJS app and the HTTP server

Install and Run

  1. You must have node and git installed. It's recommended to have mongod installed too, so that the data is preserved across application restarts.

  2. Clone the repo.

  3. cd loopback-example-offline-sync

  4. npm install - install the root package dependencies.

  5. npm install grunt-cli -g - skip if you have Grunt CLI already installed.

  6. npm install bower -g - skip if you already have Bower installed.

  7. bower install - install front-end scripts

  8. mongod - make sure mongodb is running if you want to run with NODE_ENV=production.

  9. grunt serve - build and run the entire project in development mode.

  10. open http://localhost:3000 - point a browser at the running application.

Project layout

The project is composed from multiple components.

  • common/models/ contains definition of models that are shared by both the server and the client.

  • client/lbclient/ provides an isomorphic loopback client with offline synchronization. The client needs some client-only models for data synchronization. These models are defined in client/lbclient/models/.

  • client/ngapp/ is a single-page AngularJS application scaffolded using yo angular, with a few modifications to make it work better in the full-stack project.

  • server/ is the main HTTP server that brings together all other components. Also сontains the REST API server; it exposes the shared models via REST API.

Build

This project uses Grunt for the build, since that's what yo angular creates.

There are three major changes from the generic Gruntfile required for this full-stack example:

  • grunt serve uses the server/ component instead of grunt connect.

  • lbclient component provides a custom build script (lbclient/build.js) which runs browserify to produce a single js file to be used in the browser. The Gruntfile contains a custom task to run this build.

  • The definition of Angular routes is kept in a standalone JSON file that is used by the server/ component too. To make this JSON file available in the browser, there is a custom task that builds ngapp/config/bundle.js.

Targets

  • grunt serve starts the application in development mode, watching for file changes and automatically reloading the application.
  • grunt test runs automated tests (only the front-end has tests at the moment).
  • grunt build creates the bundle for deploying to production.
  • grunt serve:dist starts the application serving the production bundle of the front-end SPA.
  • grunt jshint checks consistency of the coding style.

Adding more features

Define a new shared model

The instructions assume the name of the new model is 'MyModel'.

  1. Create a file models/my-model.json, put the model definition there. Use models/todo.json as an example, see loopback-boot docs for more details about the file format.

  2. (Optional) Add models/my-model.js and implement your custom model methods. See models/todo.js for an example.

  3. Add an entry to rest/models.json to configure the new model in the REST server:

    {
      "MyModel": {
        "dataSource": "db"
      }
    }
  4. Define a client-only model to represent the remote server model in the client - create lbclient/models/my-model.json with the following content:

    {
      "name": "RemoteMyModel",
      "base": "MyModel"
    }
  5. Add two entries to lbclient/models.json to configure the new models for the client:

    {
      "MyModel": {
        "dataSource": "local"
      },
      "RemoteMyModel": {
        "dataSource": "remote"
      }
    }
  6. Register the local model with Angular's injector in ngapp/scripts/services/lbclient.js:

      .value('MyModel', app.models.LocalMyModel)

Create a new Angular route

Since the full-stack example project shares the routes between the client and the server, the new route cannot be added using the yeoman generator.

  1. (Optional) Create a new angular controller using yeoman, for example,

    $ yo angular:controller MyModel
  2. (Optional) Create a new angular view using yeoman, for example,

    $ yo angular:view models
  3. Add a route entry to ngapp/config/routes.json, for example,

    {
      "/models": {
        "controller": "MymodelCtrl",
        "templateUrl": "/views/models.html"
      }
    }

More LoopBack examples

loopback-example-offline-sync's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

loopback-example-offline-sync's Issues

Errors when running, "serve" task broken, "serve:dist" works

Following the Install and Run section in the README results in

  • works with "grunt serve:dist"
  • broken with "grunt serve"

This on a pristine ubuntu server 14.04 vagrant box, with nodejs and npm coming from the distro's packages. Versions:

  • ubuntu server 14.04 LTS
  • npm 1.3.10
  • node v0.10.25
  • bower 1.3.12

The output of "grunt test" brings up the same error I'm getting at the browser's console:

PhantomJS 1.9.7 (Linux) ERROR
  ReferenceError: Can't find variable: setImmediate
  at /vagrant/examples/loopback-example-full-stack/client/lbclient/browser.bundle.js:34621

Browsers used were Chrome (38.0.2125.101 beta (64-bit)) and Firefox (32.0.3+build1-0ubuntu0.12.04.1).

The bug being that a person following the README to the letter won't get a working example.

gulp error: ./bower_components missing?

gulp build is failing on a require statement in html5/app.html5.js. build environment is OS X, 10.9.3, node, git, gulp and mongodb all installed:

box-2:loopback-example-full-stack jwilliams$ gulp
[20:10:24] Warning: gulp version mismatch:
[20:10:24] Running gulp is 3.7.0
[20:10:24] Local gulp (installed in gulpfile dir) is 3.6.2
[20:10:24] Using gulpfile ~/Documents/rubicon/src/loopback-example-full-stack/gulpfile.js
[20:10:24] Starting 'build'...
building api
building html5
building web
[20:10:26] Starting 'run'...
[gulp] [nodemon] v1.2.0
[gulp] [nodemon] to restart at any time, enter rs
[gulp] [nodemon] watching: /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/*/
[gulp] [nodemon] starting node --debug web/app.js
debugger listening on port 5858

events.js:72
throw er; // Unhandled 'error' event
^
Error: module "./bower_components/angular/angular.js" not found from "/Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/html5/app.html5.js"
at notFound (/Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/index.js:811:15)
at /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/index.js:761:23
at /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/node_modules/browser-resolve/index.js:185:24
at /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/node_modules/resolve/lib/async.js:36:22
at load (/Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/node_modules/resolve/lib/async.js:54:43)
at /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/node_modules/resolve/lib/async.js:60:22
at /Users/jwilliams/Documents/rubicon/src/loopback-example-full-stack/node_modules/browserify/node_modules/resolve/lib/async.js:16:47
at Object.oncomplete (fs.js:107:15)
box-2:loopback-example-full-stack jwilliams$ ls
README.md api bower.json gulpfile.js html5 models models.json node_modules package.json web
box-2:loopback-example-full-stack jwilliams$

Refactor the layout of front-end files

The current layout in loopback-example-full-stack is too prescriptive about the layout of the front-end code and makes it difficult to use tools like generator-angular.

The distinction between html5 and web does not work very well, as the templates in html5 depend on CSS styles that are defined in web/css.

using mysql as a datasource

Hi guys, I am using mysql as my datasource. I have added my models accordingly and I get my models in my controller.

Did a console log of one of the models and I get this:
Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}

Doing the code below will result to TypeError: Cannot read property 'then' of undefined

Channel.find().$promise.then(function (result) {
  console.log(result);
});

What seems to be the problem? Why I am not getting my data from the model?

Other observations:
Using the generated loopback-angular-ui-router, I was able to get my data. Doing a console log of one of the models resulted to this:
function v(a){f(a||{},this)}

Whereas in this example, doing a consol log of one of the models resulted to this:
ModelClass = function ModelConstructor(data, options) {

Fine-grained access control: What does "not fully support" mean?

Sadly I found the following sentence at end of the Synchronization docs.

Known issues
LoopBack does not fully support fine-grained access control to a selected subset of model instances, therefore it is not possible to replicate models where the user can access only a subset of instances (for example only the instances the user has created).

I implement a role based access control were groups of users have access on resources. Users can be members of different groups. I solved this by extra fields in the desired models via a mixin and a role resolver. As @fabien proposed here ( strongloop/loopback#238 ) I used applyScope to make sure that only the necessary amount of data is load from datasource. Normal API requests works as expected.

BUT when it comes to synchronization it seems there is no way to separate only some resources. Especially for mobile applications it makes no sense to synchronize all data of a datasource not only because of the amount of data also because of data security concerns.

How can I reduce the "changes" (and diff and checkpoint) requests only to that resources that are stored in LocalStorage or those remote resources which are accessible for the actual user?

Can someone give me an advice which approach I should use to solve this?

Postgres - Editing a record

Editing a Todo - creates an index violation as it tries to add the same record into my Todo table.

See attached screenshot...

capture

-- Table: todo

CREATE TABLE todo
(
title text,
completed boolean,
created double precision,
id text NOT NULL,
CONSTRAINT pkid PRIMARY KEY (id)
)
WITH (
OIDS=FALSE
);
ALTER TABLE todo
OWNER TO postgres;

Mssql - error when creating a Todo

From within the loopback-example-full-stack.

npm install loopback-connector-mssql.

Set up datasources with a new mssql connection.

Change model config for Todo to use mssql.

slc arc - then migrate the Todo model into sql server.

grunt serve

Attempt to add a Todo... todo sync fails...

On /api/Todos/bulk-update
"conversion failed when converting from a character string to uniqueidentifier"

See attached screenshot.

capture

Mongo duplicate key error E11000

When I attempt to use Mongo instead of memory db, I get duplicate key error and the server crashes, is there a specific configuration I am missing to prevent this?

The following is the error when the server crashes:

Fatal error: MongoError: insertDocument :: caused by :: 11000 E11000 duplicate key error index: todo-example.Todo-change.$id dup key: { : "fe2de28e9d5f36a4215241c6a94b42f73a7798c2" }

$ cat server/datasources.json
{
  "db": {
    "connector": "mongodb",
    "defaultForType": "db",
    "hostname": "localhost",
    "port": 27017,
    "database": "todo-example"
  }
}
$ mongo
> use todo-example
switched to db todo-example
> show collections
Todo
Todo-change
checkpoint
system.indexes
> db.Todo.find({})
{ "_id" : "t-3860", "title" : "asdfasdf", "completed" : false, "created" : 1412640133531 }
> db['Todo-change'].find({})
{ "_id" : "0d065308a81ec04500adcf44aee4c81f77b5eb8a", "rev" : null, "prev" : "5f064762539627a72472b260d021b8d916e7c296", "checkpoint" : 0, "modelName" : "Todo", "modelId" : "t-7872" }
{ "_id" : "5a5a86de9a2d33b58339ae9faebc3d5dd0df4e3a", "rev" : null, "prev" : "7c41efa447632e95b056b81fb3ba8f414d14e75a", "checkpoint" : 0, "modelName" : "Todo", "modelId" : "t-8483" }
{ "_id" : "fe2de28e9d5f36a4215241c6a94b42f73a7798c2", "rev" : "29a6799bbb5ac0977f8555a234c0855586c33104", "checkpoint" : 0, "modelName" : "Todo", "modelId" : "t-3860" }
> db.checkpoint.find({})
{ "_id" : ObjectId("54332d7c763961ff61d20d82"), "seq" : 0, "time" : ISODate("2014-10-07T00:02:04.789Z"), "sourceId" : null }
{ "_id" : ObjectId("54332d7c763961ff61d20d83"), "seq" : 0, "time" : ISODate("2014-10-07T00:02:04.790Z"), "sourceId" : null }
> db.system.indexes.find({})
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "todo-example.Todo" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "todo-example.Todo-change" }
{ "v" : 1, "key" : { "_id" : 1 }, "name" : "_id_", "ns" : "todo-example.checkpoint" }
$ node --version
v0.10.32
$ npm --version
2.1.2

Failed to create Embedded Model in the client side

I created a Model named Project where ProjectMembers are embedded model. Here are my model:
Project.json
{
"name": "Project",
"base": "PersistedModel",
"strict": "throw",
"persistUndefinedAsNull": true,
"trackChanges": true,
"properties": {
...
},
"relations": {
"members": {
"type": "embedsMany",
"model": "ProjectMember",
"property": "members",
"options": {
"validate": true,
"forceId": false
}
}
}
}
ProjectMember.json
{
"name": "ProjectMember",
"base": "Model",
"idInjection": true,
"properties": {
...
},
"validations": [],
"relations": {},
"acls": [],
"methods": []
}
In the server side model-config.json I updated the datasource as below:
"Project": {
"dataSource": "my_db"
},
"ProjectMember": {
"dataSource": "transient"
}
And in the client side in lbclient/models/ I added 2 files local-project.json and remote-project.json as exactly same as local-todo.json and remote-todo.json.
I updated the client side model-config.json file as below:
"RemoteProject": {
"dataSource": "remote"
},
"LocalProject": {
"dataSource": "local"
}

In the client controller I run the following codes:
ProjectModel.create($scope.project)
.then(function(project) {
var owner = loginDetails.getLoginUser();// the member
owner.role = 'owner';
owner.status = 'active';
project.members.create(owner); //shows error: couldn't read property
$scope.project = {};
$scope.$apply();
});
It creates the Project but failed to create the embedded model. It displays "Couldn't read property create undefined"? Is there any way to create embedded model in the client side?

Primus

how can I use Primus or SockJS for continuous synchronization instead of socket.io?

Request expects at least host or hostname, but none given in browser mode

The todo app's 'sync' button throws this error:

Uncaught Error: Invalid URI "/api/Todos/checkpoint"

And debugging I find that Request fails on this line:

if (!(self.uri.host || (self.uri.hostname && self.uri.port)) && !self.uri.isUnix) {

since we only call with a relative path.

Should it be necessary to make requests with an absolute uri? That would be silly for browsers, but if must for now, so be it...

Merge `api` and `web` into single component

The api/ component of the full-stack example seems rather anaemic to me. It calls loopback-boot to configure a loopback app and then basically exposes loopback.rest().

Once #17 is done, web/ component would become very small too. Since all front-end resources will have been moved to the client component, the web component will only expose the client and the api in a single server.

I am proposing to merge these two components into a single server/ directory.

Once merged, it will be easy to move the registration of middleware from app.js to a set of boot/ scripts loaded by loopback-boot.

none isomorphic data sync and error in datasources.local.js

Hello!

I need a offline data sync to use in an ionic app so i need it to be none isomorphic. This loopback example is broken for me. Every time i use to different browsers on my local machine to make changes it make conflicts that cannot me resolved.

Trying to resolve result in this:

Error: Duplicate entry for LocalTodo.id

Also i had to update:

module.exports = { remote: { url: GLOBAL_CONFIG.restApiUrl } };

To

module.exports = { remote: { url: 'http://localhost:3000'+GLOBAL_CONFIG.restApiUrl } };

For it just to semi work with server sync.

Is there anyone who got a working example of loopback offline sync with none isomorphic code?

grunt serve:dist produce empty uglified js files

Hi there,
I succeeded with grunt serve, etc.
when using grunt serve: dist, the process seems to end successfully, I start the app normally at localhost:3000, as well as the REST explorer, BUT the index.html page looks have no links (Home, Login, Register have no link).
Having a look at the files, I found that the generated scripts.d41d8cd9.js and vendor.d41d8cd9.js are empty.
As I am new to many of these topics, I would appreciate some hints.

here is the console log of the grunt serve:dist command:

C:\...\loopback-example-full-stack-master>grunt serve:
dist
Running "serve:dist" (serve) task

Running "clean:dist" (clean) task
Cleaning .tmp...OK

Running "build-lbclient" task

Running "build-config" task

Running "wiredep:app" (wiredep) task

Running "useminPrepare:html" (useminPrepare) task
Configuration changed for concat, uglify, cssmin

Running "concurrent:dist" (concurrent) task

Running "copy:styles" (copy) task
Copied 1 files

Done, without errors.

Running "imagemin:dist" (imagemin) task
Minified 0 images (saved 0 B)

Done, without errors.

Running "svgmin:dist" (svgmin) task
Total saved: 0 B

Done, without errors.

Running "autoprefixer:dist" (autoprefixer) task
File .tmp/styles/main.css created.

Running "concat:generated" (concat) task
File .tmp\concat\scripts\vendor.js created.
File .tmp\concat\scripts\scripts.js created.

Running "ngAnnotate:dist" (ngAnnotate) task
>> 2 files successfully generated.

Running "copy:dist" (copy) task
Copied 9 files

Running "cdnify:dist" (cdnify) task
Going through client/dist/index.html to update script refs
? bower_components/angular/angular.js changed to //ajax.googleapis.com/ajax/libs
/angularjs/1.2.26/angular.min.js
? bower_components/angular-route/angular-route.js changed to //ajax.googleapis.c
om/ajax/libs/angularjs/1.2.26/angular-route.min.js

Running "cssmin:generated" (cssmin) task
>> Destination not written because minified CSS was empty.
File client\dist\styles\main.css created: 9.8 kB → 7.54 kB

Running "uglify:generated" (uglify) task

Running "filerev:dist" (filerev) task
? client/dist/scripts/scripts.js changed to scripts.d41d8cd9.js
? client/dist/scripts/vendor.js changed to vendor.d41d8cd9.js
? client/dist/styles/main.css changed to main.291524af.css

Running "usemin:html" (usemin) task
Replaced 7 references to assets

Running "usemin:css" (usemin) task
Replaced 1 reference to assets

Running "htmlmin:dist" (htmlmin) task
Minified client/dist/index.html 1.43 kB → 1.28 kB
Minified client/dist/views/changes.html 1.94 kB → 1.6 kB
Minified client/dist/views/login.html 43 B → 41 B
Minified client/dist/views/register.html 46 B → 44 B
Minified client/dist/views/todos.html 4.28 kB → 3.38 kB
Minified client/dist/views/user.html 42 B → 40 B
Minified client/dist/views/welcome.html 90 B → 87 B

Running "run:dist:keepalive" (run) task
loopback deprecated The model Todo is tracking changes, which requries a string
id with GUID/UUID default value. events.js:180:16
Browse your REST API at http://localhost:3000/explorer
Web server listening at: http://localhost:3000/
express deprecated res.sendfile: Use res.sendFile instead server\boot\angular-ro
utes.js:7:13

[windows] gulp error: Cannot find module 'local.config'

Hi,
when starting from scratch (by manual), I get 2 errors - in step "npm install" I get this error:

npm ERR! peerinvalid The package loopback-datasource-juggler does not satisfy its siblings' peerDepe
ndencies requirements!
npm ERR! peerinvalid Peer [email protected] wants [email protected]
npm ERR! peerinvalid Peer [email protected] wants [email protected]

npm ERR! System Windows_NT 6.1.7601
npm ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\n
pm\bin\npm-cli.js" "install"
npm ERR! cwd d:\projects\loopback-example-full-stack
npm ERR! node -v v0.10.26
npm ERR! npm -v 1.4.3
npm ERR! code EPEERINVALID
npm ERR!
npm ERR! Additional logging details can be found in:
npm ERR! d:\projects\loopback-example-full-stack\npm-debug.log
npm ERR! not ok code 0

and when building the app using "gulp" command, I get another error:

module.js:340
throw err;
^
Error: Cannot find module 'local.config'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (d:\projects\loopback-example-full-stack\web\app.js:6:20)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

What should I set, please?
Thank you
Lukas

Uncaught TypeError: Cannot read property 'seq' of undefined

While "connected," I get "isConnected? true" in the Javascript console followed by the following error: "Uncaught TypeError: Cannot read property 'seq' of undefined." This occurs when I go to the /my/todos route and also occurs when I create a new todo.

While using two browser windows at that same route and after the aforementioned error occurs, the newly created todo doesn't show up in the other window until after I create a todo (in the second browser window).

The error doesn't show up when I'm "offline".

MongoDB - edit record failing

Editing a Todo - fails to update the database, and then causes a conflict as the DB version is different to the local version.

See attached screenshot of console errors in Google Chrome...

capture

Include sourcemaps for the minified code

Modify the browserify build to generate source maps when the output is minified.

FWIW, there is minifyify module which should do exactly what we want. Except I was not able to make the example code from README work in html5/configure.js

ReferenceError: loopback is not defined

When running the app I get ReferenceError: loopback is not defined. Here's the output.

➜ gulp
[21:47:58] Using gulpfile ~/Sites/samples/Loopback/full-stack/gulpfile.js
[21:47:58] Starting 'build'...
building lbclient
[21:48:00] Starting 'run'...
[gulp] [nodemon] v1.2.0
[gulp] [nodemon] to restart at any time, enter rs
[gulp] [nodemon] watching: /Users/jboothe/Sites/samples/Loopback/full-stack/*/

[gulp] [nodemon] starting node --debug web/app.js
debugger listening on port 5858
failed to require "/Users/jboothe/Sites/_samples/Loopback/full-stack/api/boot/change-tracking.js"

/Users/jboothe/Sites/_samples/Loopback/full-stack/node_modules/loopback-boot/lib/executor.js:158
throw e;
^
ReferenceError: loopback is not defined
at Function.app.model (/Users/jboothe/Sites/_samples/Loopback/full-stack/node_modules/loopback/lib/application.js:144:39)
at Object. (/Users/jboothe/Sites/_samples/Loopback/full-stack/api/boot/change-tracking.js:5:8)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at tryRequire (/Users/jboothe/Sites/_samples/Loopback/full-stack/node_modules/loopback-boot/lib/executor.js:151:20)
at /Users/jboothe/Sites/_samples/Loopback/full-stack/node_modules/loopback-boot/lib/executor.js:143:19
building lbclient
[gulp] [nodemon] app crashed - waiting for file changes before starting...
lbclient was built
building api
api was built
building html5
lbclient was built
building api
api was built
building html5
html5 was built
building web
web was built
[21:48:04] Finished 'build' after 5.85 s
html5 was built
building web
web was built
[21:48:05] Finished 'run' after 4.95 s
[21:48:05] Starting 'default'...
[21:48:05] Finished 'default' after 18 μs

Not working on Firefox/iceweasel 31

Give some errors on firefox 31.

ReferenceError: cleanup is not defined
Model.on('deletedAll', cleanup);
browser.bundle.js (línea 28919, col 2)

and

Error: [$injector:unpr] Unknown provider: TodoProvider <- Todo
http://errors.angularjs.org/1.2.21/$injector/unpr?p0=TodoProvider%20%3C-%20Todo
minErr/<@http://localhost:3000/bower_components/angular/angular.js:78:5
createInjector/providerCache.$injector<@http://localhost:3000/bower_components/angular/angular.js:3776:13
getService@http://localhost:3000/bower_components/angular/angular.js:3904:11
createInjector/instanceCache.$injector<@http://localhost:3000/bower_components/angular/angular.js:3781:17
getService@http://localhost:3000/bower_components/angular/angular.js:3904:11
invoke@http://localhost:3000/bower_components/angular/angular.js:3931:1
instantiate@http://localhost:3000/bower_components/angular/angular.js:3951:7
$ControllerProvider/this.$get</<@http://localhost:3000/bower_components/angular/angular.js:7244:7
ngViewFillContentFactory/<.link@http://localhost:3000/bower_components/angular-route/angular-route.js:911:13
nodeLinkFn@http://localhost:3000/bower_components/angular/angular.js:6677:1
compositeLinkFn@http://localhost:3000/bower_components/angular/angular.js:6070:13
publicLinkFn@http://localhost:3000/bower_components/angular/angular.js:5966:30
$CompileProvider/this.$get</createBoundTranscludeFn/boundTranscludeFn@http://localhost:3000/bower_components/angular/angular.js:6090:13
controllersBoundTransclude@http://localhost:3000/bower_components/angular/angular.js:6697:11
update@http://localhost:3000/bower_components/angular-route/angular-route.js:869:17
$RootScopeProvider/this.$get</Scope.prototype.$broadcast@http://localhost:3000/bower_components/angular/angular.js:12911:15
$RouteProvider/this.$get</updateRoute/<@http://localhost:3000/bower_components/angular-route/angular-route.js:550:15
qFactory/defer/deferred.promise.then/wrappedCallback@http://localhost:3000/bower_components/angular/angular.js:11520:15
qFactory/defer/deferred.promise.then/wrappedCallback@http://localhost:3000/bower_components/angular/angular.js:11520:15
qFactory/ref/<.then/<@http://localhost:3000/bower_components/angular/angular.js:11606:11
$RootScopeProvider/this.$get</Scope.prototype.$eval@http://localhost:3000/bower_components/angular/angular.js:12632:9
$RootScopeProvider/this.$get</Scope.prototype.$digest@http://localhost:3000/bower_components/angular/angular.js:12444:15
$RootScopeProvider/this.$get</Scope.prototype.$apply@http://localhost:3000/bower_components/angular/angular.js:12736:13
done@http://localhost:3000/bower_components/angular/angular.js:8339:34
completeRequest@http://localhost:3000/bower_components/angular/angular.js:8553:7
createHttpBackend/</xhr.onreadystatechange@http://localhost:3000/bower_components/angular/angular.js:8496:1

<div class="ng-scope" ng-view="">

[windows] Error: Cannot find module 'api'

while running gulp I get "Error: Cannot find module 'api'" After patching #25 with what described in the thread.

module.js:340
throw err;
^
Error: Cannot find module 'api'
at Function.Module._resolveFilename (module.js:338:15)
at Function.Module._load (module.js:280:25)
at Module.require (module.js:364:17)
at require (module.js:380:17)
at Object. (C:\Users\Acaspita\Documents\Tests\loopback-example-full-stack\web\app.js:8:11)
at Module._compile (module.js:456:26)
at Object.Module._extensions..js (module.js:474:10)
at Module.load (module.js:356:32)
at Function.Module._load (module.js:312:12)
at Function.Module.runMain (module.js:497:10)

Help?

web: Express 4.x routing

Move all express routes to web/routes.

// web/routes/index.js
var router = loopback.Router(); // introduced in express 4.x
module.exports = router;

// define all routes on `router`

Modify web/app to add the router middleware at the appropriate point:

app.use(require('./routes'));

Requires strongloop/loopback#293, #22 and probably #17 too.

Iteration 2 - make the infrastructure more generic

List of things we need to improve in this example to make it a basis for loopback-workspace 3.0.

  • 1. Multiple datasources
  • 2. Dynamic configuration of datasources
  • 3. Reduce boilerplate, auto-load components
    • a. Extract most of api/app.api.js to loopback core.
    • b. Figure out how to simplify html5/app.html5.js
    • c. Refactor custom Grunt tasks into a module
    • d. There should be a convention for adding new things by adding a new file, without modifying any existing code.
  • 4. Automated tests
    • Integration tests for the models and the api server
    • Unit-tests for the html5 client which do not communicate with the backend
    • End-to-end tests - html5 client, api server, models, datasources
  • 5. Mix and match components

1. Multiple datasources

The current design of api/app.api.js seems to supports a single db datasource. This is a step back from what we already have in loopback-workspace, where datasources.json can define multiple different datasources.

Here is a list of datasources used by a fully-featured application:

  • db for the main database
  • push for push notifications
  • email for sending e-mails
  • rest or soap for getting data from legacy systems
  • storage for managing images via loopback-storage-service

On the client side, most models will be attached to the same Remoting datasource. The most notable exception is synchronization, it requires several datasources (local storage, remoting).

(SLA-1023)

2. Dynamic configuration of datasources

The current design makes it easy to change the db configuration depending on environment variables. While this is useful for demo purposes, our current direction regarding deployment & operations favours different approach - see the gist.

Configuration should not be present in a node application archive. The more configuration is bound in, the less choice there will be over deployment environment. Even deploying the same app to staging and then production could become impossible.

We need to keep in mind the use case of loopback-workspace, which should be able to load a list of available datasource without the need to build the project and load it to a Node.js process via require('app.js').

(SLA-1023)

3. Reduce boilerplate, auto-load components

The current version contains too much of boilerplate code and makes it impossible to add new features/models/datasources via loopback-workspace.

Here are few generators that cannot be implemented now:

  • add a new model
  • add a new datasource
  • enable explorer (swagger)
  • enable authentication

What is needed:

a. Extract most of api/app.api.js to loopback core. Ideally the existing method app.boot can be modified or extended to support the new layout.

b. Figure out how to simplify html5/app.html5.js. The code to require() all models should be generated by gulpfile, same applies to the code calling require() for all angular controller files.

c. (SLA-938) Refactor most of gulpfile into a module gulp-loopback, so that the application gulpfile contains only calls to gulp-loopback and application-specific options.

d. There should be a convention for adding new things by adding a new file, without modifying any existing code. All components (api, html5, web) should support these conventions, either directly in code (think of app.boot) or via a custom build step. (See also b.)

4. Automated tests

The pull request #1 touched the subject lightly, but no solution was implemented.

I would like to see at least these three categories of tests covered by the example project:

a. (SLA-841) Integration tests for the models and the api server, the tests are permitted to use the database (probably the real one, possibly an in-memory replacement). These tests should run on Node.js.

b. (SLA-1019) Unit-tests for the html5 client which do not communice with the backend. These tests should run in a browser via Karma.

c. (SLA-1020) End-to-end tests - html5 client, api server, models, datasources. There are two flavours: in the first one, developers write unit-test-like code, but the communication with backend is not mocked out. The second flavour tests the application via selenium or a similar framework (e.g. angular's protractor). Both flavours require to start the server before running the tests in the browser.

5. Mix and match components

To keep the loopback-workspace code simple, we should come up with a single structure flexible enough to support different kinds of projects:

  • full-stack server + client as presented here: api, models, html5, web.
  • a pure API server: api, models
  • a website with REST API: api, models, web
  • (optional) a website without REST API: models, web

The current design is pretty close, but not there yet.

Sync specific data

Can it do like, sync the objects I own but not other?

Or for cases like groups in a chat application, only groups I belong to.

error running example

Hi,

I'm trying to run the example and getting the following error after pulling the repo and doing : 'npm install'

npm ERR! peerinvalid The package loopback-datasource-juggler does not satisfy its siblings' peerDependencies requirements!
npm ERR! peerinvalid Peer [email protected] wants [email protected]
npm ERR! peerinvalid Peer [email protected] wants [email protected]

npm ERR! System Darwin 13.2.0
npm ERR! command "node" "/usr/local/bin/npm" "install"
npm ERR! cwd /Users/xxxx/loopback-example-full-stack
npm ERR! node -v v0.10.28
npm ERR! npm -v 1.4.9
npm ERR! code EPEERINVALID
npm ERR!

What do I need to do to get the full stack example running? Any help much appreciated. Thanks.

To big for a web app?

I am investigating if loopback might work for me and I understand that this app is just a demo.
However what I found here scared me - In order to run this tiny todo app it takes mega bytes to download on the client.

I did the following steps:

cloned the repository
ran grunt
went to client/lbclient/
executed du -sm browser.bundle.js
Result 6MB (!!)

Is strongloop for phonegap apps only?

Where's my index.html file? explainer

For all of the benefits this approach brings they come at a cost in that a develper is going to have to learn a different orientation to build their apps.

index.html is a universally understood touchstone for frontend developers so it's a logical starting point in the transition to a new 'opinion'

Move models.json into /models

/to @bajtos @raymondfeng @seanbrookes

From a previous discussion

There should be a convention for adding new things by adding a new file, without modifying any existing code.

I really like this approach. I think we should adopt it for models as well. This would mean all model definitions would exist as models/*.json.

For this app it would look like:

/models
  /todo.json
  /todo.js
  /user.json
  ...

todo.json would be the typical models.json definition just in a separate file.

todo.js would be the extensions to the todo definition. One simplification we might want to do is the todo.js file could define the model by requiring the todo.json file.

// todo.js
var Todo = module.exports = loopback.PersistedModel.extend('Todo', require('./todo.json'));

This would close the gap between hand written models and generated models. There isn't a lot of boilerplate that we would have to generate either. We would have to generate the additional files. This should be simple to add to the workspace.

.extend() could support the definition format of todo.json without much modification.

Grunt build does not work properly

Hi,
I'm really interested in using this full-stack example as a project structure with build automation but I'm running into an issue. 'grunt serve' works just fine but when I run the 'grunt build' the script in the client/dist/scripts.c95494af.js is empty therefore the 'grunt serve:dist' is not running properly.

I googled quite a lot and tried to play with the grunt config file with no success. Can you please help me to start on the right foot.

Running "clean:dist" (clean) task
Verifying property clean.dist exists in config...OK
Files: .tmp, client/dist/favicon.ico, client/dist/index.html, client/dist/robots.txt, client/dist/scripts, client/dist/scripts/scripts.c95494af.js, client/dist/scripts/vendor.d41d8cd9.js, client/dist/styles, client/dist/styles/main.291524af.css, client/dist/views, client/dist/views/changes.html, client/dist/views/login.html, client/dist/views/register.html, client/dist/views/todos.html, client/dist/views/user.html, client/dist/views/welcome.html
Options: force=false, no-write=false
Options: force=false, no-write=false
Cleaning .tmp...OK
Cleaning client/dist/favicon.ico...OK
Cleaning client/dist/index.html...OK
Cleaning client/dist/robots.txt...OK
Cleaning client/dist/scripts...OK
Cleaning client/dist/styles...OK
Cleaning client/dist/views...OK

Running "build-lbclient" task

Running "build-config" task

Running "wiredep" task

Running "wiredep:app" (wiredep) task
Verifying property wiredep.app exists in config...OK
Files: client/ngapp/index.html
Verifying property wiredep.app.src exists in config...OK
Options: src=["client/ngapp/index.html"], ignorePath={}, cwd="client/ngapp", bowerJson={"name":"loopback-example-full-stack","version":"0.0.0","homepage":"https://github.com/strongloop/loopback-example-full-stack","authors":["Sam Roberts <[email protected]>"],"license":"MIT","private":true,"appPath":"client/ngapp","testPath":"client/ngapp/test/spec","ignore":["**/.*","node_modules","**/bower_components","test","tests"],"dependencies":{"angular":"~1.2.16","json3":"~3.3.1","es5-shim":"~3.1.0","angular-route":"~1.2.16"},"devDependencies":{"angular-mocks":"~1.2.16","angular-scenario":"~1.2.16"}}, directory="./bower_components"

Running "useminPrepare" task

Running "useminPrepare:html" (useminPrepare) task
Verifying property useminPrepare.html exists in config...OK
Files: client/ngapp/index.html -> html
Options: dest="client/dist", flow={"html":{"steps":{"js":["concat","uglifyjs"],"css":["cssmin"]},"post":{}}}
Going through client/ngapp/index.html to update the config
Looking for build script HTML comment blocks

Configuration is now:

  concat:
  { generated: 
   { files: 
      [ { dest: '.tmp/concat/scripts/vendor.js',
          src: 
           [ '../bower_components/es5-shim/es5-shim.js',
             '../bower_components/angular/angular.js',
             '../bower_components/json3/lib/json3.js',
             '../bower_components/angular-route/angular-route.js' ] },
        { dest: '.tmp/concat/scripts/scripts.js',
          src: 
           [ 'client/lbclient/browser.bundle.js',
             'client/config/bundle.js',
             'client/scripts/app.js',
             'client/scripts/services/lbclient.js',
             'client/scripts/controllers/home.js',
             'client/scripts/controllers/user.js',
             'client/scripts/controllers/todo.js',
             'client/scripts/controllers/login.js',
             'client/scripts/controllers/register.js',
             'client/scripts/controllers/change.js' ] } ] } }

  uglify:
  { generated: 
   { files: 
      [ { dest: 'client/dist/scripts/vendor.js',
          src: [ '.tmp/concat/scripts/vendor.js' ] },
        { dest: 'client/dist/scripts/scripts.js',
          src: [ '.tmp/concat/scripts/scripts.js' ] } ] } }

  cssmin:
  { generated: 
   { files: 
      [ { dest: 'client/dist/styles/vendor.css', src: [] },
        { dest: 'client/dist/styles/main.css',
          src: [ '.tmp/styles/main.css' ] } ] } }

Running "concurrent:dist" (concurrent) task
Verifying property concurrent.dist exists in config...OK
Files: [no src] -> dist
Options: limit=4

Running "concat:generated" (concat) task
Verifying property concat.generated exists in config...OK
Files: [no src] -> .tmp/concat/scripts/vendor.js
Files: client/lbclient/browser.bundle.js -> .tmp/concat/scripts/scripts.js
Options: separator="\n", banner="", footer="", stripBanners=false, process=false, sourceMap=false, sourceMapName=undefined, sourceMapStyle="embed"
Writing .tmp/concat/scripts/vendor.js...OK
File .tmp/concat/scripts/vendor.js created.
Reading client/lbclient/browser.bundle.js...OK
Writing .tmp/concat/scripts/scripts.js...OK
File .tmp/concat/scripts/scripts.js created.

Running "ngAnnotate" task

Running "ngAnnotate:dist" (ngAnnotate) task
Verifying property ngAnnotate.dist exists in config...OK
Files: .tmp/concat/scripts/scripts.js -> .tmp/concat/scripts/scripts.js
Files: .tmp/concat/scripts/vendor.js -> .tmp/concat/scripts/vendor.js
Options: (none)
Reading .tmp/concat/scripts/scripts.js...OK
Writing .tmp/concat/scripts/scripts.js...OK
Reading .tmp/concat/scripts/scripts.js...OK
Writing .tmp/concat/scripts/scripts.js...OK
Reading .tmp/concat/scripts/vendor.js...OK
Writing .tmp/concat/scripts/vendor.js...OK
Reading .tmp/concat/scripts/vendor.js...OK
Writing .tmp/concat/scripts/vendor.js...OK
>> 2 files successfully generated.

Running "copy:dist" (copy) task
Verifying property copy.dist exists in config...OK
Files: client/ngapp/favicon.ico -> client/dist/favicon.ico
Files: client/ngapp/robots.txt -> client/dist/robots.txt
Files: client/ngapp/index.html -> client/dist/index.html
Files: client/ngapp/views/changes.html -> client/dist/views/changes.html
Files: client/ngapp/views/login.html -> client/dist/views/login.html
Files: client/ngapp/views/register.html -> client/dist/views/register.html
Files: client/ngapp/views/todos.html -> client/dist/views/todos.html
Files: client/ngapp/views/user.html -> client/dist/views/user.html
Files: client/ngapp/views/welcome.html -> client/dist/views/welcome.html
Options: encoding="utf8", processContent=false, processContentExclude=[], mode=false
Copying client/ngapp/favicon.ico -> client/dist/favicon.ico
Reading client/ngapp/favicon.ico...OK
Writing client/dist/favicon.ico...OK
Copying client/ngapp/robots.txt -> client/dist/robots.txt
Reading client/ngapp/robots.txt...OK
Writing client/dist/robots.txt...OK
Copying client/ngapp/index.html -> client/dist/index.html
Reading client/ngapp/index.html...OK
Writing client/dist/index.html...OK
Copying client/ngapp/views/changes.html -> client/dist/views/changes.html
Reading client/ngapp/views/changes.html...OK
Writing client/dist/views/changes.html...OK
Copying client/ngapp/views/login.html -> client/dist/views/login.html
Reading client/ngapp/views/login.html...OK
Writing client/dist/views/login.html...OK
Copying client/ngapp/views/register.html -> client/dist/views/register.html
Reading client/ngapp/views/register.html...OK
Writing client/dist/views/register.html...OK
Copying client/ngapp/views/todos.html -> client/dist/views/todos.html
Reading client/ngapp/views/todos.html...OK
Writing client/dist/views/todos.html...OK
Copying client/ngapp/views/user.html -> client/dist/views/user.html
Reading client/ngapp/views/user.html...OK
Writing client/dist/views/user.html...OK
Copying client/ngapp/views/welcome.html -> client/dist/views/welcome.html
Reading client/ngapp/views/welcome.html...OK
Writing client/dist/views/welcome.html...OK
Copied 9 files

Running "cdnify" task

Running "cdnify:dist" (cdnify) task
Verifying property cdnify.dist exists in config...OK
File: [no files]
Reading bower.json...OK
Parsing bower.json...OK
Options: cdn="google"
Going through client/dist/index.html to update script refs
Reading client/dist/index.html...OK
✔ bower_components/angular/angular.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular.min.js
✔ bower_components/angular-route/angular-route.js changed to //ajax.googleapis.com/ajax/libs/angularjs/1.2.26/angular-route.min.js
Writing client/dist/index.html...OK

Running "cssmin" task

Running "cssmin:generated" (cssmin) task
Verifying property cssmin.generated exists in config...OK
Files: [no src] -> client/dist/styles/vendor.css
Files: .tmp/styles/main.css -> client/dist/styles/main.css
Options: report="min"
>> Destination not written because minified CSS was empty.
Reading .tmp/styles/main.css...OK
Writing client/dist/styles/main.css...OK
File client/dist/styles/main.css created: 9.8 kB → 7.54 kB

Running "uglify" task

Running "uglify:generated" (uglify) task
Verifying property uglify.generated exists in config...OK
Files: .tmp/concat/scripts/vendor.js -> client/dist/scripts/vendor.js
Files: .tmp/concat/scripts/scripts.js -> client/dist/scripts/scripts.js
Options: banner="", footer="", compress={"warnings":false}, mangle={}, beautify=false, report="min", expression=false
Minifying with UglifyJS...Reading .tmp/concat/scripts/vendor.js...OK
OK
Writing client/dist/scripts/vendor.js...OK
File client/dist/scripts/vendor.js created: 0 B → 0 B
Minifying with UglifyJS...Reading .tmp/concat/scripts/scripts.js...OK
OK
Writing client/dist/scripts/scripts.js...OK
File client/dist/scripts/scripts.js created: 3.67 MB → 464.74 kB

Running "filerev" task

Running "filerev:dist" (filerev) task
Verifying property filerev.dist exists in config...OK
Files: client/dist/scripts/scripts.js, client/dist/scripts/vendor.js, client/dist/styles/main.css
Options: encoding="utf8", algorithm="md5", length=8
Reading client/dist/scripts/scripts.js...OK
✔ client/dist/scripts/scripts.js changed to scripts.c95494af.js
Reading client/dist/scripts/vendor.js...OK
✔ client/dist/scripts/vendor.js changed to vendor.d41d8cd9.js
Reading client/dist/styles/main.css...OK
✔ client/dist/styles/main.css changed to main.291524af.css

Running "usemin" task

Running "usemin:html" (usemin) task
Verifying property usemin.html exists in config...OK
Files: client/dist/index.html, client/dist/views/changes.html, client/dist/views/login.html, client/dist/views/register.html, client/dist/views/todos.html, client/dist/views/user.html, client/dist/views/welcome.html -> html
Options: type="html", assetsDirs=["client/dist","client/dist/images"]
Processing as HTML - client/dist/index.html
Update the HTML to reference our concat/min/revved script files
scripts/vendor.js changed to scripts/vendor.d41d8cd9.js
scripts/scripts.js changed to scripts/scripts.c95494af.js
Update the HTML with the new css filenames
styles/main.css changed to styles/main.291524af.css
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/index.html...OK
Processing as HTML - client/dist/views/changes.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/changes.html...OK
Processing as HTML - client/dist/views/login.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/login.html...OK
Processing as HTML - client/dist/views/register.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/register.html...OK
Processing as HTML - client/dist/views/todos.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/todos.html...OK
Processing as HTML - client/dist/views/user.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/user.html...OK
Processing as HTML - client/dist/views/welcome.html
Update the HTML to reference our concat/min/revved script files
Update the HTML with the new css filenames
Update the HTML with the new img filenames
Update the HTML with the new video filenames
Update the HTML with the new poster filenames
Update the HTML with the new source filenames
Update the HTML with data-main tags
Update the HTML with data-* tags
Update the HTML with background imgs, case there is some inline style
Update the HTML with anchors images
Update the HTML with reference in input
Update the HTML with the new img filenames in meta tags
Update the HTML with the new object filenames
Update the HTML with the new image filenames for svg xlink:href links
Update the HTML with the new image filenames for src links
Update the HTML with the new image filenames for srcset links
Update the HTML within the <use> tag when referencing an external url with svg sprites as in svg4everybody
Writing client/dist/views/welcome.html...OK
Replaced 7 references to assets

Running "usemin:css" (usemin) task
Verifying property usemin.css exists in config...OK
Files: client/dist/styles/main.291524af.css -> css
Options: type="css", assetsDirs=["client/dist","client/dist/images"]
Processing as CSS - client/dist/styles/main.291524af.css
Update the CSS to reference our revved images
Writing client/dist/styles/main.291524af.css...OK
Replaced 1 reference to assets

Running "htmlmin" task

Running "htmlmin:dist" (htmlmin) task
Verifying property htmlmin.dist exists in config...OK
Files: client/dist/index.html -> client/dist/index.html
Files: client/dist/views/changes.html -> client/dist/views/changes.html
Files: client/dist/views/login.html -> client/dist/views/login.html
Files: client/dist/views/register.html -> client/dist/views/register.html
Files: client/dist/views/todos.html -> client/dist/views/todos.html
Files: client/dist/views/user.html -> client/dist/views/user.html
Files: client/dist/views/welcome.html -> client/dist/views/welcome.html
Options: collapseWhitespace, conservativeCollapse, collapseBooleanAttributes, removeCommentsFromCDATA, removeOptionalTags
Reading client/dist/index.html...OK
Writing client/dist/index.html...OK
Minified client/dist/index.html 1.43 kB → 1.28 kB
Reading client/dist/views/changes.html...OK
Writing client/dist/views/changes.html...OK
Minified client/dist/views/changes.html 1.94 kB → 1.6 kB
Reading client/dist/views/login.html...OK
Writing client/dist/views/login.html...OK
Minified client/dist/views/login.html 43 B → 41 B
Reading client/dist/views/register.html...OK
Writing client/dist/views/register.html...OK
Minified client/dist/views/register.html 46 B → 44 B
Reading client/dist/views/todos.html...OK
Writing client/dist/views/todos.html...OK
Minified client/dist/views/todos.html 4.28 kB → 3.38 kB
Reading client/dist/views/user.html...OK
Writing client/dist/views/user.html...OK
Minified client/dist/views/user.html 42 B → 40 B
Reading client/dist/views/welcome.html...OK
Writing client/dist/views/welcome.html...OK
Minified client/dist/views/welcome.html 90 B → 87 B

Done, without errors.

Execution Time (2015-01-09 05:21:51 UTC)
loading tasks 6ms 0%
clean:dist 18ms 0%
build-lbclient 3.1s ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 19%
build-config 3ms 0%
wiredep:app 238ms ▇▇▇ 1%
useminPrepare:html 55ms 0%
concurrent:dist 3.8s ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 23%
autoprefixer:dist 93ms ▇ 1%
concat:generated 68ms 0%
ngAnnotate:dist 1.5s ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 9%
copy:dist 13ms 0%
cdnify:dist 2.2s ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 14%
cssmin:generated 37ms 0%
uglify:generated 5.1s ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 31%
filerev:dist 13ms 0%
usemin:html 20ms 0%
usemin:css 5ms 0%
htmlmin:dist 23ms 0%
Total 16.3s

User authentication

Can you please include the user model and how to authenticate remote requests.

I have been trying to implement this for a while now with no luck.

Easy-to-read GUIDs

See outdated diff comment @ #60 (comment)

- Todo.beforeSave = function(next, model) {

  • if (!model.id) model.id = 't-' + Math.floor(Math.random() * 10000).toString();
  • Todo.observe('before save', function(ctx, next) {
  • if (!ctx.Model.id)
  •  ctx.Model.id = 't-' + Math.floor(Math.random() \* 10000).toString();
    

This hook is no longer needed, the id property is initialised by loopback to a new GUID.

I think the idea here was to use small semi-unique numbers that are easier to read than full GUIDs.

I am proposing to make a following change in the GUI to make IDs easier to read:

take the first 8 characters of the generated uid (the 4 low bytes of the timestamp)
use proquint- to convert these 8 characters into a readable string
show this readable representation in all place where we were rendering the original id (mostly conflict >resolution views?)
Feel free to make UI changes in a new pull request. However, the hook should be removed as part of this patch.

Possible loopback-boot regression

/cc @bajtos

{ name: 'AssertionError',
  actual: false,
  expected: true,
  operator: '==',
  message: 'cannot autoAttach model "Email". No dataSource found of type mail' }

This is a regression. I'm guessing it is coming from the new boot() implementation or the new datasources.*.

Todo Edit - sync with MongoDB - gives E11000 duplicate key error index

Issue Overview

I forked the loopback-example-full-stack and then created a datasource for mongoDB - mongo version 3.0.1.
Then i changed the todo model to use mongodb as a datasource.

Creating and deleting a todo works OK - but if I try to edit a Todo I get a duplicate key error;

MongoError: E11000 duplicate key error index: test.Todo.$id dup key: { : "t-2159" }

Forked at

https://github.com/anupsaund/loopback-example-full-stack

One commit

anupsaund@a8ea1a4

Screenshot

todoedit

Type of property "id" changes from "string" to "number"

I'm using LoopBack as Backend with MySQL as a datastore. Everything works as expected even with relation between objects and ACL-checks.

Now I want to create a app with offline-sync functionality.

I defined a Person model on server side according to the docs (http://docs.strongloop.com/display/public/LB/Synchronization) like this:

{
  "name": "Person", 
  "base": "PersistedModel", 
  "strict": "validate", 
  "trackChanges": true, 
  "persistUndefinedAsNull": true,
  "mixins": { ... },
  "properties": {
    "id": {
      "id": true,
      "type": "string",
      "defaultFn": "guid"
    },
    "firstname": {
      "type": "string",
      "required": false
    },
    ...
  },
  "validations": [],
  "relations": {
    ...
  },
  "acls": [
    ...
  ],
  "methods": []
}

In database I changed the id column type to varchar(255) in Person table and added the tables "Person-change" and "checkpoint". About this step I didn't found much documentation. Only this: https://groups.google.com/d/msg/loopbackjs/LfFtXvjK-VA/6aYLqaayEAwJ

CREATE TABLE IF NOT EXISTS `Person-change` (
 `id` varchar(255) NOT NULL,
 `rev` varchar(512) DEFAULT NULL,
 `prev` varchar(512) DEFAULT NULL,
 `checkpoint` int(11) DEFAULT NULL,
 `modelName` varchar(512) DEFAULT NULL,
 `modelId` varchar(512) DEFAULT NULL,
 PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `checkpoint` (
 `id` int(11) NOT NULL AUTO_INCREMENT,
 `seq` int(11) DEFAULT NULL,
 `time` datetime DEFAULT NULL,
 `sourceId` varchtyar(512) DEFAULT NULL,
 PRIMARY KEY (`id`)
);

During the start process of the server I get this message:

loopback deprecated The model Person is tracking changes, 
which requries a string id with GUID/UUID default value. at events.js:180:16

I found the same error related with the grunt build script in issue #58.

I tried to dive in code but I don't feel that I come closer to a solution.
In "Registry.createModel" and "ModelBuilder.define" the type of property id is "string". Later in "DataSource.setupDataAccess" and "PersistedModel.enableChangeTracking" the type of property id is "Function: Number".

Because of the changed id type the call of Person.create({ ... data without id... }, function(err, result) {}); leads to a mysql error (Column 'id' cannot be null).

{"code":"ER_BAD_NULL_ERROR","errno":1048,"sqlState":"23000","index":0}

At first I thought it is may a race conditions problem because the generation of the uuid. In "result" of the callback function is not null and the id is present (as uuid) but there are no data stored in mysql.

I found a different way of property setup here (https://github.com/strongloop/loopback-example-offline-sync/blob/master/common/models/todo.json - with some missing options) but this produces the same result.

How do I set up the properties right? In which cases set properties will be ignored and overwritten by default id type of datastore?

Thanks in Advance.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.