Amazon S3 photo uploads (cfs:gridfs cfs:s3) in a grid layout solution? Can't get Isotope/Masonry to work


#1

I tried doing something like this http://stackoverflow.com/questions/17047975/how-to-do-a-pinterest-like-ui-layout-in-meteor-edited-anyone-use-cast-js but it seems imagesLoaded doesn’t work like it’s supposed to on deploy. It gets fired before the images have loaded basically. I was told this may have to do with how the images are streamed from Amazon S3 using cfs:s3. Anyone have success getting Amazon S3 photo uploads to work with a grid library like Isotope?


#2

I’m not quite sure what exactly your problem is. Do you mean you won’t see the images right after you’ve uploaded them to S3, or do you mean that your templates does not render them when you try to download them from S3?


#3

Oh sorry. The images upload and appear fine. I am having issue with getting Isotope to work.

I think the problem is that Isotope initializes too early, and that the imagesLoaded library doesn’t work properly with images that come from Amazon S3.

Isotope needs to initialize after the images have been downloaded from S3, rendered, and shown on the page. Is there a function out there that checks this? Putting it in template.___.rendered is too early unless there is something I’m missing.

I was able to get the code to work locally, but not in deployment because it takes longer to get the images, and Isotope is initialized before that happens.


#4

I don’t think the problem is the download from Amazon here. I had similar problems with 3rd party JS libraries, because I (naively) thought that onRendered() actually means that the page has already been rendered.

But I’ve experienced that this is not always the case. So many 3rd party libraries fail to initialize if you just try to call them in the onRendered handler.

I found two solutions to this problem so far:

  1. Isolating the external component in its own (smaller) sub-template, i.e. putting only the HTML code and JS code of your grid in its own template. I don’t know why exactly, but sometimes this helped wonders, especially if you subscribe to a collection before you can actually render the images.

  2. Delayed initialization of the 3rd party component using a Meteor.setTimeout() in the onRendered() method. This seems to give Blaze enough time to render the DOM completely. I also tried to use Tracker.afterFlush() for this, but this did not help.


#5

Oh my goodness. You’re right. Sure enough, it worked with Meteor.setTimeout(). There has got to be a better way to do this! Someone PLEASE enlighten us.

I have a slight Backbone background and there is a onRender and onShow. Something like would go in an onShow I believe.

I was also naive. .rendered should definitely mean the page has been rendered. What in the world does it mean then? >.> It’s even in the darn example http://docs.meteor.com/#/full/template_onRendered, but if I used packery like that in my app… it wouldn’t work.

Should I just replace my view layer with React or what?


#6

Well, as far as I know React does not even support other DOM manipulating libraries. That’s one of the reasons why I am still using Blaze.


#7

You need to use this thing with Isotope, it will work as you expect.


#8

I mentioned in my first post that it doesn’t… unless I’m doing something wrong.

Template.home.onRendered = function() {
  var $container = $('.grid');

  $container.imagesLoaded(function() {
    $container.isotope({
      itemSelector : '.image'
    });
  });
};

Doesn’t get any more straightforward, so I have no idea what I’m missing.

In my deployment, isotope is definitely initializing before the images have fully loaded. It somewhat works locally, but still getting overlap because it’s getting run before all the images have loaded. Seems like it only buys a bit of time but not enough in deployment.


I'm creating Meteor learning material. What would you like to see?
#9

There is a good discussion here about what I am trying to achieve. It is a bit above my head, but I will try a few things mentioned when I have some time: How can I register a callback to be invoked when a template is re-rendered?

Thought this may be useful for others trying to do the same: just trying to get Isotope to load correctly and adjust when images are added or removed. Someone out there should make a tutorial. :slight_smile:


#10

I tried to do the same task, managed to render elements, but adding/changing/removing was not so easy (I was only starting to use Meteor), so I used flex grid.

If you know Meteor really well, you can make it work. You will definitely need imagesloaded with no cache support - don’t know, if the author added this option. You can check my imagesloaded package, it worked for me.

Wish you good luck and enough patience, I know this path :wink: