Skip to content
This repository has been archived by the owner on Mar 14, 2019. It is now read-only.

FS.File

Mateusz Bochyński edited this page Jan 4, 2017 · 5 revisions

An FS.File instance is an object with properties similar to this:

{
  _id: '',
  collectionName: '', // this property not stored in DB
  collection: collectionInstance, // this property not stored in DB
  createdByTransform: true, // this property not stored in DB
  data: data, // this property not stored in DB
  original: {
    name: '',
    size: 0,
    type: '',
    updatedAt: date 
  },
  copies: {
    storeName: {
      key: '',
      name: '',
      size: 0,
      type: '',
      createdAt: date,
      updatedAt: date 
    }
  },
  uploadedAt: date,
  anyUserDefinedProp: anything
}

But name, size, type, and updatedAt should be retrieved and set with the methods rather than directly accessing the props:

// get original
fileObj.name();
fileObj.extension();
fileObj.size();
fileObj.formattedSize(); // must add the "numeral" package to your project to use this method
fileObj.type();
fileObj.updatedAt();

// get for the version in a store
fileObj.name({store: 'thumbs'});
fileObj.extension({store: 'thumbs'});
fileObj.size({store: 'thumbs'});
fileObj.formattedSize({store: 'thumbs'}); // must add the "numeral" package to your project to use this method
fileObj.type({store: 'thumbs'});
fileObj.updatedAt({store: 'thumbs'});

// set original
fileObj.name('pic.png');
fileObj.extension('png');
fileObj.size(100);
fileObj.type('image/png');
fileObj.updatedAt(new Date);

// set for the version in a store
fileObj.name('pic.png', {store: 'thumbs'});
fileObj.extension('png', {store: 'thumbs'});
fileObj.size(100, {store: 'thumbs'});
fileObj.type('image/png', {store: 'thumbs'});
fileObj.updatedAt(new Date, {store: 'thumbs'});

These methods can all be used as UI helpers, too:

{{#each myFiles}}
  <p>Original name: {{this.name}}</p>
  <p>Original extension: {{this.extension}}</p>
  <p>Original type: {{this.type}}</p>
  <p>Original size: {{this.size}}</p>
  <p>Thumbnail name: {{this.name store="thumbs"}}</p>
  <p>Thumbnail extension: {{this.extension store="thumbs"}}</p>
  <p>Thumbnail type: {{this.type store="thumbs"}}</p>
  <p>Thumbnail size: {{this.size store="thumbs"}}</p>
{{/each}}

Also, rather than setting the data property directly, you should use the attachData method.

Check out the full public API for FS.File.

Storing FS.File references in your objects

NOTE: At the moment storing FS.File - References in MongoDB on the server side doesn't work. See eg. (https://github.com/CollectionFS/Meteor-cfs-ejson-file/issues/1) (https://github.com/CollectionFS/Meteor-CollectionFS/issues/356) (https://github.com/meteor/meteor/issues/1890).

_Instead store the id's of your file objects and then fetch the FS.File-Objects from your CollectionFS - Collection.

Often your files are part of another entity. You can store a reference to the file directly in the entity. You need to add cfs:ejson-file to your packages with meteor add cfs:ejson-file. Then you can do for example:

// Add file reference of the event photo to the event
var file = $('#file').get(0).files[0];
var fileObj = eventPhotos.insert(file);
events.insert({
  name: 'My Event',
  photo: fileObj
});

// Later: Retrieve the event with the photo
var event = events.findOne({name: 'My Event'});
// This loads the data of the photo into event.photo
// You can include it in your collection transform function.
event.photo.getFileRecord();

Demo app

You need to ensure that the client is subscribed to the related photo document, too. There are packages on atmosphere, such as publish-with-relations and smart-publish, that attempt to make this easy. When you are using publish-with-relations package define files property as a collection parameter. For example:

...
mappings: [{reverse: true, collection: Photos.files, key: 'photoId'}];
...

In simple cases, you may also be able to return an array from Meteor.publish:

Meteor.publish("memberAndPhotos", function (userId) {
  check(userId, String);
  return [
    Collections.Members.find({userId: userId}, {fields: {secretInfo: 0}}),
    Collections.Photos.find({
      $query: {'metadata.owner': userId},
      $orderby: {uploadedAt: -1}
    });
  ];
});