Console error: image not found - angularjs

Some context:
I'm using a .twig file to display some .png images, like this
<img class="output-icons" src="{{ asset('path/to/images/output_icon_' ~ '{{ output.slug }}' ~ '.png') }}">
The images are all named output_icon_(output.slug).png; output.slug has 11 different slugs, same number of pictures I have. here's a picture name example: output_icon_balance.png.
So far so good, it all works as it should, but even tho all 11 pictures are being displayed, the console is showing this
GET URL/path/output_icon_%7B%7B%20output.slug%20%7D%7D.png?v2212 404 not found

You have to use ng-src to render images defined on your scope. The reason is that browser will read it as {{variable}} assigned to your src tag instead of rendering it first and then assigning. So, ng-src will make sure that your variable is first rendered and then assigned to your tag.
For more Info:
https://docs.angularjs.org/api/ng/directive/ngSrc

Related

Integrating code via partials on a Hugo site not working

I am running an open source comment engine on my server which I want to integrate to my Hugo site.
After doing all the listed things below, the comment section is not visible, and only the heading appears.
What are the possible reasons for this and error and how can I solve it?
So I created a partials file for It, added some code in single.hmtl and edited my config.toml correspondingly.
This is what's inside my partial file named commento.html:
<div id="commento"></div>
<script defer src="{{ .Site.Params.CommentoURL }}/js/commento.js"></script>
<noscript>Please enable JavaScript to load the comments.</noscript>
This is what's inside my single.html file:
{{ if and .Site.Params.CommentoURL (and (not .Site.BuildDrafts) (not .Site.IsServer)) -}}
<h2>Comments</h2>
{{ partial "commento.html" . }}
{{- end }}
and I added the commentoURL parameter in config.toml file like this:
CommentoURL = "http://qwerty.abc:8080"
Please Inspect the output HTML. I am pretty sure you will find this empty div:
<div id="commento"></div>
This means that your Javascript is broken. This has nothing to do with Hugo, partials or even Hugo themes. You probably also have a red error in your Javascript console. This is what you should focus on.

Image Processing in Hugo

I am using the following code {{< figure src="../img/img.png" title="the image title" >}} to display image on hugo website and it works fine. I found this piece of code from: Add image to webpage which uses hugo framework
Now I wanted to do some image processing and was using the following link: https://gohugo.io/content-management/image-processing/
I was trying to use the following lines of code:
{{ $image := resources.Get "images/sunset.jpg" }}
{{ $image := resources.GetRemote "https://gohugo.io/img/hugo-logo.png" }}
For first line in above code, the folder structure is as follows. Inside the blog-code(root folder) I created assets/images, with sunset.jpg inside. It does not work i.e. image is not displayed on the page.
Folder Structure
blog-code/assets/images/sunset.jpg
The second line in above code is fetching a remote image. It also does not work.
I have tried following link, Processing images in Hugo, and few other links but not able to solve the issue.
Please guide, where I am getting wrong.
Thanks.
{{ $image := resources.Get "images/sunset.jpg" }} <- you're getting the image resource and assigning to a variable
<img src="{{$image.Permalink}}"> <- now you are giving the image resources URI to the src attribute
You're referenced link DOES show this exact pattern.
Reading the Hugo Docs for Image processing:
https://gohugo.io/content-management/image-processing/#readout
Seems like what you need so you do not fall prey to misunderstanding.
It does not work i.e. image is not displayed on the page.
This code:
{{ $image := resources.Get "images/sunset.jpg" }}
does not display an image, it only sets the variable $image.

Why does an un-rendered element behave as if it has been rendered?

I am slightly confused by this behaviour of Angular JS.
Angular.js' ng-if will not render an element if the expression evaluates to false, if the documents are anything to go by. I have this piece of code in my html template:
<div ng-if="false">
<img src="{{ imgPath }}" />
<p>This block is not rendered</p>
</div>
// In the controller
$scope.imgPath = "/invalid/image/path";
When this template is rendered, I cannot, as expected, see the img element or the p element on developer tools:
However... when I look at the network tab, there is a request to fetch the image:
I thought that if the element is not rendered, it wouldn't function in any way or form since it doesn't exist... Why does the browser fetch the image in this case?
You can see the working code on plnkr here, you'll have to hit F12 to watch the error on the console.
I know that using ng-src= {{ }} instead of src={{ }} would solve the issue of img src being fetched with unresolved expression before the data is bound, but, this question deals more with why ng-if isn't stopping the request in the first place
It takes AngularJS a small amount of time to process your markup. So, intially when your page loads, the browser does it's thing trying to process the markup. It sees this:
<div ng-if="false">
<img src="{{ imgPath }}" />
<p>This block is not rendered</p>
</div>
But, so far, AngularJS has not been loaded, and the AngularJS directives have no meaning. The browser attempts to load an image located at the literal URL of : {{ imgPath }}, which the URL encoder will translate to %7B%7B%20imgPath%20%7B%7B, which will fail (obviously). Still, AngularJS has not been loaded.
Once AngularJS finally loads, it goes through the DOM and applies the ngIf directive and removes the node.
This is why you want to use ngSrc. This will prevent the image request, since the browser doesn't understand the ng-src directive and won't treat it like a src attribute.

Why am I getting a 404 error with ng-src even though image is appearing?

I am displaying an image with ng-src:
<img style="width: 100px" ng-src="{{absolutePath}}customImages/{{currentBook.idcode}}.png"/>
which is found and displays fine, however in Firebug console, I am getting this error:
NetworkError: 404 Not Found - http://localhost/learntracker/customImages/.png"
as if this is being executed before the variables exist.
This HTML code exists inside a <div ng-cloak ng-app="mainModule"> and ng-cloak I understand to stop any executing before the variables exist.
Why is this error occurring and how can I suppress it?
Looks like you might be loading the data which populates currentBook object asynchronously. So during the previous digest cycle, ng-src directive would have rendered the src for the image with no value for currentBook.idcode and once it gets populated on the scope, another digest cycle runs updating the image. So the previous causes the 404. You could place an ng-if on the image.
ex:-
<img style="width: 100px" ng-if="currentBook.idcode"
ng-src="{{absolutePath}}customImages/{{currentBook.idcode}}.png"/>
You could see an small demo implementation here
But this seems to have been fixed with 1.3.x version of angular, in-order to prevent rendering of image src before all the interpolations are expanded to get values. Plnkr
ng-cloak is only helpful not to expose interpolation expression briefly while the angular is loading.
Some additional info (Courtesy #zeroflagL ) :
With angular version 1.3.x ng-src makes use of all or nothing interpolation (feature addition to interpolateProvider), meaning it will not expand the directive unless all the bound interpolations are resolved. You can see this mapping in the compile provider source.
ALL_OR_NOTHING_ATTRS = makeMap('ngSrc,ngSrcset,src,srcset'),
What you might want to do in this case is to actually have a function on scope that creates the ULR for the image path:
<img style="width: 100px" ng-if="currentBook.idcode" ng-src="getImagePath(currentBook.idcode)">
var absolutePath = 'somepath/';
$scope.getImagePath = function(idcode) {
return absolutePath + 'customImages/' + idcode + '.png';
}

Use of ng-src vs src

This tutorial demonstrates the use of the directive ngSrc instead of src :
<ul class="phones">
<li ng-repeat="phone in phones" class="thumbnail">
<img ng-src="{{phone.imageUrl}}">
</li>
</ul>
They ask to:
Replace the ng-src directive with a plain old src attribute.
Using tools such as Firebug, or Chrome's Web Inspector, or inspecting the
webserver access logs, confirm that the app is indeed making an
extraneous request to /app/%7B%7Bphone.imageUrl%7D%7D (or
/app/{{phone.imageUrl}}).
I did so and it gave me the correct result:
<li class="thumbnail ng-scope" ng-repeat="phone in phones">
<img src="img/phones/motorola-xoom.0.jpg">
</li>
Is there a reason why?
From Angular docs
The buggy way to write it:
<img src="http://www.gravatar.com/avatar/{{hash}}"/>
The correct way to write it:
<img ng-src="http://www.gravatar.com/avatar/{{hash}}"/>
Why? this is because on load of page, before angular bootstrapping and creation of controllers, browser will try to load image from http://www.gravatar.com/avatar/{{hash}} and it will fail. Then once angular is started, it understands that that {{hash}} has to be replaced with say logo.png, now src attribute changes to http://www.gravatar.com/avatar/logo.png and image correctly loads. Problem is that there are 2 requests going and first one failing.
TO solve this we should use ng-src which is an angular directive and angular will replace ng-src value into src attribute only after angular bootstrapping and controllers are fully loaded, and at that time {{hash}} would have already been replaced with correct scope value.
<img ng-src="{{phone.imageUrl}}">
This gives you expected result, because phone.imageUrl is evaluated and replaced by its value after angular is loaded.
<img src="{{phone.imageUrl}}">
But with this, the browser tries to load an image named {{phone.imageUrl}}, which results in a failed request.
You can check this in the console of your browser.
The src="{{phone.imageUrl}}" is unnecessary and creates an extra request by the browser. The browser will make at least 2 GET requests attempting to load that image:
before the expression is evaluated {{phone.imageUrl}}
after the expression is evaluated img/phones/motorola-xoom.0.jpg
You should always use ng-src directive when dealing with Angular expressions. <img ng-src="{{phone.imageUrl}}"> gives you the expected result of a single request.
On a side note, the same applies to ng-href so you don't get broken links till the first digest cycle kicks in.
Well actually it makes 100% sense because HTML gets processed sequentially and when this HTML page is being processed line by line, by the time it gets to this image, the line and processing the image, our phone.imageUrl is not yet defined yet.
And in fact, Angular JS has not yet processed this chunk of HTML, and hasn't yet looked for these placeholders and substitute these expressions with the values. So what ends up happening is that the browser gets this line and tries to fetch this image at this URL.
And of course this is a bogus URL, if it still has those mustache and curly braces in it, and therefore it gives you a 404, but once of course Angular takes care of this, it substitutes this URL for the proper one, and then we still see the image, but yet the 404 error message remains in our console.
So, how can we take care of this? Well, we can not take care of this using regular HTML tricks. But, we can take care of it using Angular. We need somehow to tell the browser not to try to fetch this URL but at the same time fetch it only when Angular is ready for interpretation of these placeholders.
Well, one way of doing it is to put an Angular attribute on here instead of the standard HTML one. And the Angular attribute is just ng-src. So if we say that now, go back, you'll see that there's no errors anymore because the image only got fetched once Angular got a hold of this HTML and translated all the expressions into their values.

Resources