Meteor-Files: Can't read property 'versions' of undefined

/* html */
<template name="uploadForm2">
  {{#with currentUpload}}
    Uploading <b>{{file.name}}</b>: 
    <span id="progress">{{progress.get}}%</span>
  {{else}}
    <input id="fileInput" type="file" />
    <p><small>Upload file in <code>jpeg</code> or <code>png</code> format, with size less or equal to 10MB</small></p>
  {{/with}}
</template>

<template name="uploadedFiles2">
  {{#if uploadedFiles.count}}
    <ul>
      {{#each uploadedFiles.each}}
        <li>
          <a href="{{link}}?download=true" download="{{name}}">{{name}}</a>
           <img src="{{link}}" alt="{{name}}" /> 
           <a class="js-remove btn">Remove</a>
        </li>
      {{/each}}
    </ul>
  {{else}}
    <div>No files uploaded, yet</div>
  {{/if}}
</template>
/* .js */
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';

import { Collections } from '../../api/images/images.js';
import './file-upload-page.html';

Template.uploadForm2.onCreated(function fileUploadPageOnCreated() {
  this.currentUpload = new ReactiveVar(false);
  this.autorun(() => {
    this.subscribe('files.images.all');
  });
});

Template.uploadedFiles2.helpers({
  uploadedFiles: function () {
    return Collections.files.find();
  },
});

Template.uploadedFiles2.events({
  'click .js-remove': function (e, template) {
    this.remove(function (error) {
      if (error) {
        console.error('File(s) is not removed!', error);
      }
    });
  }
});

Template.uploadForm2.helpers({
  currentUpload: function () {
    return Template.instance().currentUpload.get();
  }
});

Template.uploadForm2.events({
  'change #fileInput': function (e, template) {
    if (e.currentTarget.files && e.currentTarget.files[0]) {
      // We upload only one file, in case 
      // there was multiple files selected
      let file = e.currentTarget.files[0];
      if (file) {
        let uploadInstance = Collections.files.insert({
          file: file,
          streams: 'dynamic',
          chunkSize: 'dynamic'
        }, false);
        uploadInstance.on('start', function() {
          template.currentUpload.set(this);
        });

        uploadInstance.on('end', function(error, fileObj) {
          if (error) {
            alert('Error during upload: ' + error.reason);
          } else {
            alert('File "' + fileObj.name + '" successfully uploaded');
          }
          template.currentUpload.set(false);
        });

        uploadInstance.start();
      }
    }
  },

});
/*server */
import { FilesCollection } from 'meteor/ostrio:files';
var Dropbox, Request, bound, client, fs = {};

if (Meteor.isServer) {
  Dropbox = Npm.require('dropbox');
  Request = Npm.require('request');
  fs = Npm.require('fs');
  bound = Meteor.bindEnvironment(function(callback) {
    return callback();
  });
  client = new Dropbox.Client({
    key: 'xxxx',
    secret: 'xxxx',
    token: 'xxxx',
  });
}

const Collections = {};
Collections.files = new FilesCollection({
  debug: true, // Change to `true` for debugging
  throttle: false,
  storagePath: 'assets/app/uploads/uploadedFiles',
  collectionName: 'uploadedFiles',
  allowClientCode: true,
  onAfterUpload: function(fileRef) {
    // In onAfterUpload callback we will move file to DropBox
    var self = this;
    var makeUrl = function(stat, fileRef, version, triesUrl) {
      if (triesUrl == null) {
        triesUrl = 0;
      }
      client.makeUrl(stat.path, {
        long: true,
        downloadHack: true
      }, function(error, xml) {
        // Store downloadable link in file's meta object
        bound(function() {
          if (error) {
            if (triesUrl < 10) {
              Meteor.setTimeout(function() {
                makeUrl(stat, fileRef, version, ++triesUrl);
              }, 2048);
            } else {
              console.error(error, {
                triesUrl: triesUrl
              });
            }
          } else if (xml) {
            var upd = {
              $set: {}
            };
            upd['$set']["versions." + version + ".meta.pipeFrom"] = xml.url;
            upd['$set']["versions." + version + ".meta.pipePath"] = stat.path;
            self.collection.update({
              _id: fileRef._id
            }, upd, function(error) {
              if (error) {
                console.error(error);
              } else {
                // Unlink original files from FS
                // after successful upload to DropBox
                self.unlink(self.collection.findOne(fileRef._id), version);
              }
            });
          } else {
            if (triesUrl < 10) {
              Meteor.setTimeout(function() {
                makeUrl(stat, fileRef, version, ++triesUrl);
              }, 2048);
            } else {
              console.error("client.makeUrl doesn't returns xml", {
                triesUrl: triesUrl
              });
            }
          }
        });
      });
    };
var writeToDB = function(fileRef, version, data, triesSend) {
      // DropBox already uses random URLs
      // No need to use random file names
      if (triesSend == null) {
        triesSend = 0;
      }
      client.writeFile(fileRef._id + "-" + version + "." + fileRef.extension, data, function(error, stat) {
        bound(function() {
          if (error) {
            if (triesSend < 10) {
              Meteor.setTimeout(function() {
                writeToDB(fileRef, version, data, ++triesSend);
              }, 2048);
            } else {
              console.error(error, {
                triesSend: triesSend
              });
            }
          } else {
            // Generate downloadable link
            makeUrl(stat, fileRef, version);
          }
        });
      });
    };

    var readFile = function(fileRef, vRef, version, triesRead) {
      if (triesRead == null) {
        triesRead = 0;
      }
      fs.readFile(vRef.path, function(error, data) {
        bound(function() {
          if (error) {
            if (triesRead < 10) {
              readFile(fileRef, vRef, version, ++triesRead);
            } else {
              console.error(error);
            }
          } else {
            writeToDB(fileRef, version, data);
          }
        });
      });
    };

    var sendToStorage = function(fileRef) {
      _.each(fileRef.versions, function(vRef, version) {
        readFile(fileRef, vRef, version);
      });
    };

    sendToStorage(fileRef);
  },
  interceptDownload: function(http, fileRef, version) {
    var path, ref, ref1, ref2;
    path = (ref = fileRef.versions) != null ? (ref1 = ref[version]) != null ? (ref2 = ref1.meta) != null ? ref2.pipeFrom : void 0 : void 0 : void 0;
    if (path) {
      // If file is moved to DropBox
      // We will pipe request to DropBox
      // So, original link will stay always secure
      Request({
        url: path,
        headers: _.pick(http.request.headers, 'range', 'accept-language', 'accept', 'cache-control', 'pragma', 'connection', 'upgrade-insecure-requests', 'user-agent')
      }).pipe(http.response);
      return true;
    } else {
      // While file is not yet uploaded to DropBox
      // We will serve file from FS
      return false;
    }
  }
});
export { Collections };
if (Meteor.isServer) {
  // Intercept File's collection remove method
  // to remove file from DropBox
  var _origRemove = Collections.files.remove;

  Collections.files.remove = function(search) {
    var cursor = this.collection.find(search);
    cursor.forEach(function(fileRef) {
      _.each(fileRef.versions, function(vRef) {
        var ref;
        if (vRef != null ? (ref = vRef.meta) != null ? ref.pipePath : void 0 : void 0) {
          client.remove(vRef.meta.pipePath, function(error) {
            bound(function() {
              if (error) {
                console.error(error);
              }
            });
          });
        }
      });
    });
    // Call original method
    _origRemove.call(this, search);
  };
}

if (Meteor.isServer) {
  Collections.files.deny({
    insert() { return true; },
    update() { return true; },
    remove() { return true; },
  });
}
Here is the errors
/* server error */
I20160728-09:52:55.711(8)? [FilesCollection] [File Start Method] 20131124_125547.jpg - HP9HPqEgMfQWkZzSB
I20160728-09:52:55.731(8)? [FilesCollection] [Upload] [Start Method] Got #-1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.225(8)? [FilesCollection] [Upload] [DDP] Got #1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.376(8)? [FilesCollection] [Upload] [DDP] Got #2/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.436(8)? [FilesCollection] [Upload] [DDP] Got #3/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.515(8)? [FilesCollection] [Upload] [DDP] Got #4/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.546(8)? [FilesCollection] [Upload] [DDP] Got #5/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.561(8)? [FilesCollection] [Upload] [DDP] Got #7/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.625(8)? [FilesCollection] [Upload] [DDP] Got #6/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.638(8)? [FilesCollection] [Upload] [DDP] Got #-1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:52:56.713(8)? [FilesCollection] [Upload] [finish(ing)Upload] -> assets\app\uploads\uploadedFiles\HP9HPqEgMfQWkZzSB.jpg
I20160728-09:52:56.713(8)? [FilesCollection] [Upload] [finish(ed)Upload] -> assets\app\uploads\uploadedFiles\HP9HPqEgMfQWkZzSB.jpg
I20160728-09:52:56.729(8)? [FilesCollection] [_preCollectionCursor.observeChanges] [removed]: HP9HPqEgMfQWkZzSB
I20160728-09:52:58.326(8)? [FilesCollection] [download(/cdn/storage/uploadedFiles/HP9HPqEgMfQWkZzSB/original/HP9HPqEgMfQWkZzSB.jpg, original)]
I20160728-09:52:58.333(8)? [FilesCollection] [serve(assets\app\uploads\uploadedFiles\HP9HPqEgMfQWkZzSB.jpg, original)] [200]
I20160728-09:53:03.516(8)? [FilesCollection] [Unlink Method] [.remove(HP9HPqEgMfQWkZzSB)]
I20160728-09:53:03.535(8)? [FilesCollection] [remove("HP9HPqEgMfQWkZzSB")]
I20160728-09:53:03.537(8)? [FilesCollection] [unlink(HP9HPqEgMfQWkZzSB, undefined)]
I20160728-09:53:09.453(8)? [FilesCollection] [File Start Method] 20131124_125547.jpg - CpBqKjPi8FnWEwDc7
I20160728-09:53:09.459(8)? [FilesCollection] [Upload] [Start Method] Got #-1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:09.864(8)? [FilesCollection] [Upload] [DDP] Got #1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:09.953(8)? [FilesCollection] [Upload] [DDP] Got #2/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.019(8)? [FilesCollection] [Upload] [DDP] Got #3/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.113(8)? [FilesCollection] [Upload] [DDP] Got #4/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.212(8)? [FilesCollection] [Upload] [DDP] Got #5/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.253(8)? [FilesCollection] [Upload] [DDP] Got #7/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.331(8)? [FilesCollection] [Upload] [DDP] Got #6/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.346(8)? [FilesCollection] [Upload] [DDP] Got #-1/7 chunks, dst: 20131124_125547.jpg
I20160728-09:53:10.378(8)? [FilesCollection] [Upload] [finish(ing)Upload] -> assets\app\uploads\uploadedFiles\CpBqKjPi8FnWEwDc7.jpg
I20160728-09:53:10.378(8)? [FilesCollection] [Upload] [finish(ed)Upload] -> assets\app\uploads\uploadedFiles\CpBqKjPi8FnWEwDc7.jpg
I20160728-09:53:10.393(8)? [FilesCollection] [_preCollectionCursor.observeChanges] [removed]: CpBqKjPi8FnWEwDc7
I20160728-09:53:12.605(8)? [FilesCollection] [download(/cdn/storage/uploadedFiles/CpBqKjPi8FnWEwDc7/original/CpBqKjPi8FnWEwDc7.jpg, original)]
I20160728-09:53:12.618(8)? [FilesCollection] [serve(assets\app\uploads\uploadedFiles\CpBqKjPi8FnWEwDc7.jpg, original)] [200]
I20160728-09:53:12.775(8)? Exception in callback of async function: TypeError: Cannot read property '_id' of undefined
I20160728-09:53:12.778(8)?     at FilesCollection.exports.FilesCollection.FilesCollection.unlink (C:\projects\Testing\skillmate\.meteor\local\build\programs\server\packages\ostrio_files.js:2718:58)
I20160728-09:53:12.784(8)?     at meteor://app/imports/api/images/images.js:63:22
I20160728-09:53:12.786(8)?     at meteor://app/packages/mongo/collection.js:651:5
I20160728-09:53:12.789(8)?     at runWithEnvironment (meteor://app/packages/meteor/dynamics_nodejs.js:110:1)
I20160728-09:53:12.792(8)?     at meteor://app/packages/meteor/dynamics_nodejs.js:123:1
I20160728-09:53:12.795(8)?     at meteor://app/packages/mongo/mongo_driver.js:322:7
I20160728-09:53:12.797(8)?     at meteor://app/packages/mongo/mongo_driver.js:568:11
I20160728-09:53:12.804(8)?     at runWithEnvironment (meteor://app/packages/meteor/dynamics_nodejs.js:110:1)
I20160728-09:53:26.966(8)? [FilesCollection] [unlink(CpBqKjPi8FnWEwDc7, original)]
I20160728-09:54:21.436(8)? [FilesCollection] [Unlink Method] [.remove(CpBqKjPi8FnWEwDc7)]
I20160728-09:54:21.443(8)? [FilesCollection] [remove("CpBqKjPi8FnWEwDc7")]
I20160728-09:54:21.454(8)? [FilesCollection] [unlink(CpBqKjPi8FnWEwDc7, undefined)]

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Comments: 28 (14 by maintainers)

Most upvoted comments

Hi Dr.Dimitri , Thank you so much… The code works fine! Appreciated! Just a minor issue about the callback for deletion… I’ll figure it out.

I’m glad we’ve figured it out