Loopback and Image Uploads

4,444 views
Skip to first unread message

Abou Kone

unread,
Oct 27, 2014, 10:45:21 PM10/27/14
to loopb...@googlegroups.com
I am building a mobile backend for my mobile app (built with Ionic) and my next feature is allowing users to of course upload a profile picture, but also being able to create an image gallery from their phones. This is my first time implementing such a feature so I have been doing some research and it seems one of the best ways of handling it using the MEAN stack is to keep the picture metadata in MongoDB and the actual uploaded files in a storage service, S3 being the most prominent. I wanted to get some feedback from the community on best practices and pointers on implementing this right in Loopback, as to:

  1. Is it right to keep the metadata in MongoDB and the actual file in a third party storage (S3 and feel free to make recommendations here)?
  2. What should I be aware of in Loopback to make this happen?
  3. Any tips, recommendations, pointers would be welcome!

Thanks in advance!

Miroslav Bajtoš

unread,
Oct 28, 2014, 2:23:14 PM10/28/14
to loopb...@googlegroups.com
FWIW, there is a module loopback-component-storage that provides an abstraction over different storage providers (Amazon S3, Azure, etc.). It is supported by client SDKs like Android too.

Unfortunately it does not implement support for attaching metadata to files yet.

  1. Is it right to keep the metadata in MongoDB and the actual file in a third party storage (S3 and feel free to make recommendations here)?

Yes, that's the best approach IMO.

If you decide to try loopback-component-storage, you will have to build two models:

 - a File model to store the image data, attached to "storage" datasource
 - a FileMetadata  to store image metadata, attached to your MongoDB datasource

And link them via "hasOne" relationship: File hasOne FileMetadata as "metadata", FileMetadata hasOne File as "contents".

Miroslav

Miroslav Bajtoš

unread,
Oct 28, 2014, 2:24:30 PM10/28/14
to loopb...@googlegroups.com
See also the discussion in this GitHub issue:


Miroslav

Abou Kone

unread,
Oct 28, 2014, 2:30:53 PM10/28/14
to loopb...@googlegroups.com
Thanks Miroslav, that's a lifesaver. I knew it would be better to ask before implement something too complicated or that would be troublesome to get to work with loopback. I did not even know about the loopback-component-storage, so I would have duplicated that functionality right there. I'll add a note to the documentation discussion about that.

Abou Kone

unread,
Oct 28, 2014, 11:12:58 PM10/28/14
to loopb...@googlegroups.com
So for some reason I run into an error trying to link File and FileMetadata, 

/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/datasource.js:473
        modelClass
[r.type].call(modelClass, rn, params);
                           
^
TypeError: Cannot call method 'call' of undefined
    at
/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/datasource.js:473:28
    at
Array.forEach (native)
    at
DataSource.defineRelations (/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/datasource.js:433:28)
    at
DataSource.setupDataAccess (/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/datasource.js:515:8)
    at
DataSource.attach (/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/datasource.js:734:8)
    at
Function.ModelClass.attachTo (/Users/strongloop-api/node_modules/loopback-datasource-juggler/lib/model-builder.js:290:16)
    at
Object.registry.configureModel (/Users/strongloop-api/node_modules/loopback/lib/registry.js:174:15)
    at configureModel
(/Users/strongloop-api/node_modules/loopback/lib/application.js:396:12)
    at
EventEmitter.app.model (/Users/strongloop-api/node_modules/loopback/lib/application.js:130:5)
    at
/Users/strongloop-api/node_modules/loopback-boot/lib/executor.js:144:9

And the model definitions:

{
 
"name": "File",
 
"plural": "containers",
 
"properties": {},
 
"validations": [],
 
"relations": {
 
"metadata": {
 
"type": "belongsTo",
 
"model": "FileMetadata"
 
}


 
},
 
"acls": [],
 
"methods": []
}


{
 
"name": "FileMetadata",
 
"base": "PersistedModel",
 
"plural": "files-metadata",
 
"properties": {
   
"name": {
     
"type": "string",
     
"required": true
   
}
 
},
 
"validations": [],
 
"relations": {
   
"contents": {
     
"type": "hasOne",
     
"model": "File"
   
},


   
"container": {
     
"type": "belongsTo",
     
"model": "FileContainer",
     
"foreignKey": "fileContainerId"
   
}
 
},
 
"acls": [],
 
"methods": []
}

Any idea why? I get it on slc run.

Raymond Feng

unread,
Oct 29, 2014, 12:06:35 PM10/29/14
to loopb...@googlegroups.com
Please note relations can only be established between models attached to data sources of database type that implements CRUD behaviors. In your case, the file model is attached to the storage connector and it doesn't support relations.

Abou Kone

unread,
Oct 29, 2014, 12:08:35 PM10/29/14
to loopb...@googlegroups.com
That's what I figured. 
I've moved on to implement  the relationships dynamically using model hooks.

Red Devil

unread,
Oct 30, 2014, 2:21:02 AM10/30/14
to loopb...@googlegroups.com
If it is not much of a hassle, can you please share your code related to image upload and metadata. It will be good example for novices like me.
Thanks

Abou Kone

unread,
Oct 30, 2014, 10:47:56 AM10/30/14
to loopb...@googlegroups.com
I will as soon as I am done with it. to be precise, the front end is ionic, so AngularJS + phonegap, I am trying to upload pictures from a user's camera or gallery to S3.
If this proves to difficult to achieve  using storage-component, my plan B is tol upload directly from the UI to S3 and just create a policy signing remote hook as illustrated here:


That technique was also used for the development of the ng-s3-upload directive, which is pretty cool. Won't work for me since I am uploading from a phonegap operation but the idea is the same:


Once the upload is done I will update/create the FileMetadata in my mongo db.

@Raymond @Miroslav, this is related to a question somebody else asked:

Since we can't directly create relations between the File/Container model and the other DB based model in our application, as I said, one way to do it would be to use remote/model hooks to simulate it. I think the most efficient way to do it would be to retrieve the currently logged in user from the request after authentication but I don't see a straightforward way of doing that. Any pointers there?

Miroslav Bajtoš

unread,
Oct 31, 2014, 5:49:48 AM10/31/14
to Abou Kone, loopb...@googlegroups.com
On Thu, Oct 30, 2014 at 3:47 PM, Abou Kone <adk...@gmail.com> wrote:
@Raymond @Miroslav, this is related to a question somebody else asked:

Since we can't directly create relations between the File/Container model and the other DB based model in our application, as I said, one way to do it would be to use remote/model hooks to simulate it. I think the most efficient way to do it would be to retrieve the currently logged in user from the request after authentication but I don't see a straightforward way of doing that. Any pointers there?


Here is a code showing how to get the current user from a "beforeRemote" hook. I don't know which model and method you will have to intercept, I'll leave it up to you to figure that out.

MyModel.beforeRemote('*.save', function(ctx, unused, next) {
  if(!ctx.req.accessToken) {
    return next(new Error('must be logged in to update'));
  }
  ctx.req.accessToken.user(function(err, currentUser) {
    // your code
    next();
  });
});

Miroslav

Graham Krizek

unread,
Nov 21, 2015, 6:01:54 PM11/21/15
to LoopbackJS
I know this has been over a year since this thread was active, but I was wondering if you found a solid solution for this. I am trying to do the same thing and could really use some code to look at as a guide. 

Zvi Eintracht

unread,
May 2, 2016, 6:17:42 PM5/2/16
to LoopbackJS
same here. is there a good reference to Loopback / Ionic image upload?

Jeff Boothe

unread,
May 2, 2016, 6:20:52 PM5/2/16
to LoopbackJS
+1
Reply all
Reply to author
Forward
0 new messages