Reputation: 2848
I want to load a url from my database collection into an <img src="*url*" >
tag.
For now I simply publish/subscribe my collection and then retrive the url out of the collection and put it into the template like this:
...
Template.navigation.helpers({
logoUrl: function(){
return Img.findOne().url;
}
})
...
<template name="navigation">
<img src="{{logoUrl}}" alt="logo" >
...
The problem is, the url is loaded after everything else is loaded. That leads to the issue that for the time of pageload that image is not showing up. In case of the Logo, that is very ugly. So I want it to be there as if the url were hardcoded in the img tag.
How would I do that with Meteor?
e.g. in a PHP file i would simply say:
<?php $url = 'www.blabla.com/myurlwhatever' ?>
<img src="<?=$url ?>" >
Of course that would not be reactive, and the url would not change without reloading the whole page, but it would at least show the image instantly after the tag is loaded.
Upvotes: 0
Views: 67
Reputation: 2848
I had a concept misunderstanding here. PHP is rendered on the server. Therefore the image is directly there as soon as the page content is loaded because the whole page is prerendered. In my case above, everything was rendered on the client, which is the regular way.
So to achieve the desired result, one has to take a look at server side rendering (SSR) for Meteor. This is a huge topic and I am not sure if SSR is possible with Blaze.
A simple workaround to avoid ugly artifacts during loading, is to hide everything behind a loading screen, or at least the artifacts.
Upvotes: 0
Reputation: 53290
As you figured out, your template renders before your subscriptions are "ready", i.e. before they have received their data from the server.
The usual workaround with Blaze is to display your template (or its content) conditionally, checking whether your data is ready or not.
For example, you could simply do:
{{#if logoUrl}}
<img src="{{logoUrl}}" alt="logo" >
{{/if}}
As long as your subscription is not ready yet, logoUrl
is undefined
, and the #if
block condition is not met.
Once your subscription gets ready, the logoUrl
helper re-runs (if it finds data in your Img
collection). Provided you now have some data, the #if
block condition is now met, and your <img>
tag is displayed, with its src
attribute filled in.
Upvotes: 1
Reputation: 21
Are you sure your subscription to the collection is ready before the template gets rendered?
You might want to wait for your subscription to be ready and wrap your HTML in the following helper.
{{#if Template.subscriptionsReady }}
... html code goes in between the tags ...
{{/else}}
... show something else, for example a spinner
{{/if}}
And subscribe on the template.
Template.yourtemplatename.onCreated( function() {
this.autorun(() => {
this.subscribe('yourcollection');
});
});
I hope it helps!
Upvotes: 1