I am uploading dummy content using angular's ng-repeat.
var app = angular.module("homeApp", []);
app.controller("entriesView", function ($scope){
$scope.itemEntry = [
{
image: "img/112013-priscilla-600.jpg",
title: "ymc",
logo: "http://www.youmustcreate.com/site/wp-content/themes/youmustcreate/images/core/header-logo.jpg"
},
{
image: "https://cms.myspacecdn.com/cms/x/13/47/112013-priscilla-600.jpg"
}
];
});
HTML
<section class="miniframe-wrapper" ng-controller="entriesView">
<section ng-repeat="itemEntry in itemEntry" class="miniframe">
<img src="{{itemEntry.image}}" alt="img"/>
I noticed in inspector i am getting the Failed to load resource error however the images are appearing on my browser. Does anyone know what exactly is causing this issue. am i referencing my images correctly?
Use ng-src instead of src in your image tags when using string interpolation. ng-src parses the string then assigns the src to the tag while vanilla html is looking for an image called "{{dataEntry.image}}"
Related
I have a problem with images recently. Everything is ok until you have to show a list of images on the page.
The problem is that when we directly give an src for image with hardcoded string, it works with a url like ~/assets/any-image.png. But if I try to move url into any variable / object / array, I have to specify the :src="myVariable" which contains the URL.
The code for example:
<template>
<div>
Problem with images
<img :src="image.url" alt="">
<img :src='require(image.url)' alt="">
</div>
</template>
<script>
export default {
data () {
return {
image:
{
url: '~/assets/icon.png',
type: 'asset'
}
}
}
}
</script>
Here I tried using assets with ~ and #, also with and without slash. Of course the image exists in assets folder, but since the src url is provided via any variable (not directly), the assets url is not served and as a result the image url looks like host:port/~/assets/... which doesn't exist on the server.
In this example I've got an idea to replace image url with an object containing the url and its type (asset/static) and make checks if type asset, then use require(variable) but got the problem that "Cannot find module '~/assets/icon.png'"
Has anybody solved this problem?
You need to use require when binding to an asset variable image. For example:
<img :src="url">
url: require('#/assets/icon.png')
If your json contains only the filename, you can place require in the template:
<img :src="require('#/assets/' + url)">
url: 'icon.png'
Thanks to Dan with his answer
I've got a final solution which is universal:
Image contain it's link and type:
image: {
url: '/any-asset-folder/image.png'
type: 'asset'
}
Then with ternary operator result is
<img
:src="image.type === 'asset'
? require('#/assets'+image.url)
: image.url"
>
In this way I've got images working both if they are from assets or static or external :)
I have a fairly simple ng-repeat that iterates an AngularJS directive to display images from an array of objects, where each JSON object has a img attribute with a URL of the image. Everything works fine except in the network tools I can see that the browser is trying to load an image source URL as {{ data.img }} before being interpolated into it's actual value, it's driving me crazy trying to figure out why this is happening.
Here are the relevant pieces of my code:
index.html
<div ng-repeat="data in obj">
<feed-item></feed-item>
</div>
feedItem.html (directive)
<div class="item">
<img src="{{ data.img }}" />
</div>
Angular directive
app.directive("feedItem", function() {
return {
restrict: 'E',
templateUrl: 'assets/directives/feedItem.html',
replace: true
};
});
This results in the images rendering fine, but as mentioned the following shows up in the network tools:
All of the 2 images from the array of JSON objects are loaded fine as you can see, but I have the extra request the browser is trying to make, and the "initiator" column just says "other" which is not very helpful. Any idea why this request is being sent?
As matthewdaniel said, ng-src might solve your problem. It stops the browser from trying to load that source of the image before angular can get going, you use it just like the 'src' attribute on a normal image.
I am trying to do the following:
<div ng-repeat="audio in event.audios">
<audio ng-src="/data/media/{{audio}}" controls></audio>
</div>
But when I load the view, the {{audio}} variable is not parsed but hardcoded into the source as is. However, if for example, I place that same variable outside of the audio tag it renders the name of the audio file correctly. I've tried using both src and ng-src to no avail.
Is there a way to get the variable to work within an audio tag?
Thanks in advance.
I'm not all that familiar with the ngSrc directive outside of using it on images, but it might require an img tag somewhere in the source.
Try this:
<div ng-repeat="audio in event.audios">
<audio ng-attr-src="/data/media/{{audio}}" controls></audio>
</div>
The ng-attr- directive can be used for any attribute that doesn't have a specific role in angular. You can read more about it on this page.
Update, I was wrong.
I created a jsfiddle and found the actual error that was occurring.
You're getting an error from the sce service. See the SO question here.
The solution is to use $sce.trustAsResourceUrl().
Example:
angular.module('AudioTest', [])
.controller('AudioTestCtrl', function($scope, $sce) {
$scope.event = { 'audios': [
$sce.trustAsResourceUrl('/data/media/test1'),
$sce.trustAsResourceUrl('/data/media/test2')
]};
});
Here's the fiddle.
Update #2
If you don't want to set the url as hard coded or loop through after you get a response from the server, you can use a custom filter to accomplish what you're looking for. This method does not use interpolation, which is where the error is being thrown.
JS:
angular.module('AudioTest', [])
.filter('trustedAudioUrl', function($sce) {
return function(path, audioFile) {
return $sce.trustAsResourceUrl(path + audioFile);
};
})
.controller('AudioTestCtrl', function($scope) {
$scope.event = { 'audios': ['test1', 'test2']};
});
HTML:
<div ng-app="AudioTest">
<div ng-controller="AudioTestCtrl">
<div ng-repeat="audio in event.audios">
<audio ng-src="/data/media/ | trustedAudioUrl:audio)" controls></audio>
</div>
</div>
</div>
And the new fiddle.
Ok, thanks to theJoeBiz's input and some thinking around I solved this by making a directive, here is the code:
app.directive('audios', function($sce) {
return {
restrict: 'A',
scope: { code:'=' },
replace: true,
template: '<audio ng-src="{{url}}" controls></audio>',
link: function (scope) {
scope.$watch('code', function (newVal, oldVal) {
if (newVal !== undefined) {
scope.url = $sce.trustAsResourceUrl("/data/media/" + newVal);
}
});
}
};
});
Then on the template I used it like so:
<div ng-repeat="audio in event.audios">
<div audios code="audio"></div>
</div>
It is all working fine now.
Hey FWIW i found this page looking for a solution to template URL's for my audio tag. However I am using multiple source tags for cross browser support:
<audio id="myAudioTag">
<source ng-src="{{sceSoundUrlMp3}}">
<source ng-src="{{sceSoundUrlOgg}}">
</audio>
First I solved SCE issues by whitelisting *.ogg, *.mp3: (keep 'self' otherwise your future requests fail)
.config(function($sceDelegateProvider) {
$sceDelegateProvider.resourceUrlWhitelist([
"self",
/(mp3|ogg)$/,
]);
})
This stopped giving SCE errors but Firefox reported 'no source' and didn't notice the src tag angular added.
The last step was to call load on the element after trusting and setting $scope.sceSoundUrlMp3: $('#myAudioTag')[0].load()
I have used $sce.trustAsResourceUrl("/data/media/" + newVal) but it didn't work for.What seemed to work for me was to put document.getElementById('player').src = {{url}}
in the controller
Hope that helps someone else
I have an angularjs-Application.
In one Controller i´m waiting for an image source address - I get this from an PHP-Service.
controller.controller("LayoutCtrl",
["$scope", "$http", "$route",
function($scope, $http, $route) {
$scope.$route = $route;
$http.get('zkLib/services/header.php').success(function(data) {
$scope.header = data; });
}]);
The header.php looks like this:
$result = array();
$result['index'] = db()->loadSetting('index_page');
$result['banner'] = db()->loadSetting('site_banner');
echo json_encode($result);
So in my template i´ve written:
<div ng-controller="LayoutCtrl">
<div desc="header">
<a desc='hp_link' href="#{{header.index}}">
<img desc='banner' ng-src="zkLib/f/img/{{header.banner}}">
</a>
</div>
</div>
My Problem is now:
When the site opens, it shows the "NoImage"-Icon from the Browser while waiting for this service.
After this the image will be viewed correctly.
But in my COnsole i have this error too:
Resource interpreted as Image but transferred with MIME type text/html: "http://localhost:160/cms/app/zkLib/f/img/".
On my Server i have the image 'loading.gif', i want to show this while i´m waiting for my service.
How to solve this? Could someone help?
The reason you are getting the error in the console is because, before the request to header.php completes and angular renders {{header.banner}}, its trying to load just "zkLib/f/img/". You can fix this by putting the entire relative url into the {{header.banner}} scope property.For example...
<img desc='banner' ng-src="{{header.banner}}">
and make header.banner be the full relative path...
$http.get('zkLib/services/header.php').success(function(data) {
$scope.header = data;
$scope.bannerImage = 'zkLib/f/img/' + $scope.header.banner;
});
Now, before the request is complete, the image src will be an empty string and it won't show the broken image icon or throw the error. If you want to show a loading image before the controller loads, you can just set src, like this...
<img desc='banner' ng-src="{{bannerImage}}" src="/path/to/loading.gif">
Before the request is complete, the src will be the loading.gif file. Once the request completes, ng-src will kick in and your header.banner image will be displayed
When the controller is instantiated, $scope.header is still empty.
This makes ng-src="zkLib/f/img/{{header.banner}}" to be evaluated to this relative path:
'zkLib/f/img/' // translates to "http://localhost:160/cms/app/zkLib/f/img/"
What you need to do is to keep ng-src empty while $scope.header is empty.
#1) One way is to write this:
<img desc='banner' ng-if="header" ng-src="zkLib/f/img/{{header.banner}}">
#2) Or this (if you don't want to use ngIf):
<img desc='banner' ng-src="{{ header && 'zkLib/f/img/' + header.banner }}">
#3) But I would prefer to create the link inside the controller:
$http.get('zkLib/services/header.php').success(function(data) {
$scope.header = data;
$scope.banner = 'zkLib/f/img/' + data.banner;
});
And then just use it easily:
<img desc='banner' ng-src="{{ banner }}">
I am storing the the source string of an image to be rendered in HTML in the AngularJS controller, however it yields a 404 before the Angular controller is initialized.
Here is the HTML:
<div ng-controller="Cont">
<img src="{{imageSource}}">
</div>
Angular controller:
var Cont = function($scope) {
$scope.imageSource = '/tests.png';
}
And the error I get (%7D%7D corresponds to the {{ in the template).
GET https://localhost:9000/%7B%7BimageSource%7D%7D 404 (Not Found)
How can I prevent this from happening? That is, only load the image when the Angular controller has been initialized?
Try replacing your src with ng-src for more info see the documentation:
Using Angular markup like {{hash}} in a src attribute doesn't work
right: The browser will fetch from the URL with the literal text
{{hash}} until Angular replaces the expression inside {{hash}}. The
ngSrc directive solves this problem.
<div ng-controller="Cont">
<img ng-src="{{imageSource}}">
</div>
If someone is searching the solution for styling background-image then use this:
<div ng-style="{'background-image': 'url({{ image.source }})'}">...</div>