Unable to load data from Json file - javascript

What i'm trying to do is create an image grid layout. Similar to this but in each box is a photo which is loaded from a json file via a HTTP.get
I'm trying to create the grid layout by creating the first row and then using ng-repeat so it creates new rows.
I'm retrieving my images from a $http.get request which loads the images via a JSON file.
I cannot get the images to display and i'm unsure why. I have no errors in my console log.
This is my HTML code so far.
<div class="row" ng-repeat="" ng-if="$index % 1 === 0">
<div class="col col-33" ng-if="$index < length">
<img ng-src="{{image.image}}">
</div>
</div>

The reason your not seeing any images is because your not accessing your data properly in your HTML. Try this:
<div class="row" ng-repeat="image in data.under9s">
<div id="container" class="col col-33" ng-if="$index < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{image.image}}" />
</div>
<div id="container" class="col col-33" ng-if="$index + 1 < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{data.under9s[$index + 1].image}}" />
</div>
<div id="container" class="col col-33" ng-if="$index + 2 < data.under9s.length">
<img class="image image-list-thumb" id="image" ng-src="{{data.under9s[$index + 2].image}}" />
</div>
I think you could easily accomplish your grid using two ng-repeats. Something like:
<div class="row" ng-repeat="category in data">
<div ng-repeat="image in category" id="container" class="col col-33">
<img class="image image-list-thumb" id="image" ng-src="{{image.image}}" />
</div>
</div>

That is security issue. Either use jsonp or CORS.

Related

Simple picture gallery with enlarged thumbnails with Vue.js

I am trying to implement a simple pictures gallery in my Vue.js app.
This what I am looking for:
User click on a thumbnail and a larger picture is displayed on the right. This is the code I've done so far:
<div class="col-md-6">
<div class="row" id="grid">
<div v-for="(picture, index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<div #click="picToShow= index">
<img class="img-thumbnail img-responsive" :src="picture.picture_1">
</div>
</div>
</div>
</div>
<div class="col-6 text-center my-auto">
<div v-for="(picture,index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<img v-show="pictToShow == index" :src="picture.picture_1">
</div>
</div>
But as I run it, I get this error :
[Vue warn]: Property or method "pictToShow" is not defined on the
instance but referenced during render. Make sure that this property is
reactive, either in the data option, or for class-based components, by
initializing the property. See:
https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
I do have in my <script>:
data () {
return {
pictures: [],
picToShow: null,
}
},
How can I fix it?
You're making a typo by adding an extra t in v-show="pictToShow == index" which should be v-show="picToShow == index", but I see that it's not a good practice to make two loops, i recommend to keep the first one and use the selected index to show its image :src="pictures[picToShow].picture_1":
<div class="col-md-6">
<div class="row" id="grid">
<div v-for="(picture, index) in pictures"
:key="picture.pk"
class="col-md-4 my-auto"
>
<div #click="picToShow= index">
<img class="img-thumbnail img-responsive" :src="picture.picture_1">
</div>
</div>
</div>
</div>
<div class="col-6 text-center my-auto">
<div v-if="picToShow!==null" class="col-md-4 my-auto">
<img :src="pictures[picToShow].picture_1" />
</div>
</div>

Show multi images in a single slider page using ngb-carousel

I am using Angular 6 and ng-bootstrap and trying for a carousel.
carousel is working fine, but unable to show 4 images in one slider. it's showing 1 image in each slider.
This is the data coming via API response:
games= [{"title_id":1,"title_name":"MIssion Impossible","title_img":"https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"}]},{"title_id":2,"title_name":"Matrix","title_img":"https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"},{"id":6,"name":"Fantasy"}]},{"title_id":3,"title_name":"Avengers","title_img":"http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg","genres":[{"id":1,"name":"Action"},{"id":2,"name":"Adventure"},{"id":6,"name":"Fantasy"}]},{"title_id":4,"title_name":"Stargate SG-1","title_img":"https://image.tmdb.org/t/p/w300_and_h450_bestv2/rst5xc4f7v1KiDiQjzDiZqLtBpl.jpg","genres":[{"id":1,"name":"Action"},{"id":5,"name":"Drama"},{"id":2,"name":"Adventure"},{"id":9,"name":"Sci Fi"}]},{"title_id":5,"title_name":"Scooby Doo","title_img":"https://images-na.ssl-images-amazon.com/images/G/01/aplusautomation/vendorimages/1cdd3ea2-f14f-416b-9aaa-644a9a01ad8c.jpg._CB321085566_.jpg","genres":[{"id":1,"name":"Action"},{"id":10,"name":"Thriller"},{"id":6,"name":"Fantasy"}]}];
here is my component.html code:
<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let image of games" style="">
<div class="" style="">
<div class="col-xs-3 col-md-3 col-lg-3 col-sm-6">
<img class="" src="{{image.title_img}}" width="" >
</div>
</div>
</ng-template>
</ngb-carousel>
each image per slide it's coming.
I tried with static images as below,
<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
</ngb-carousel>
result is:
But, in mobile it's showing one below one. I need only one image to show, on click on arrow navigation next image should display
Here is one possible solution :
Separate desktop and mobile version :
Separate the desktop version with mobile version, with a ngb-carousel for each version, selected through an *ngIf. The *ngIf checks the variable mobile, defined by (see the html below) :
ngOnInit() {
if (window.screen.width === 360) { // 768px portrait
this.mobile = true;
}
}
More about it in this question.
Slider
For the mobile version, use your code (I integrated it below)
For the desktop with multiple images :
Divide you array, in a multidimensional array (first dimension for slides, second dimension for images). If you have 2 slides of 3 images, your array will be a 2*3 one.
this.games = ["a", "b", "c", "d", "e"];
this.gamesFormatted = [];
var j = -1;
for (var i = 0; i < this.games.length; i++) {
if (i % 3 == 0) {
j++;
this.gamesFormatted[j] = [];
this.gamesFormatted[j].push(this.games[i]);
}
else {
this.gamesFormatted[j].push(this.games[i]);
}
}
Display the carousel with a double loop :
<div *ngIf="games">
<!-- Mobile section : one image per slide -->
<ngb-carousel *ngIf="mobile" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let image of games">
<div class="" style="">
<div class="col-xs-3 col-md-3 col-lg-3 col-sm-6">
<img class="" src="{{image.title_img}}">
</div>
</div>
</ng-template>
</ngb-carousel>
<!-- Desktop section : multiple images per slide -->
<ngb-carousel *ngIf="!mobile" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide *ngFor="let group of gamesFormatted">
<div class="" style="" *ngFor="let game of group">
<img class="" src="{{game.title_img}}">
</div>
</ng-template>
</ngb-carousel>
</div>
I didn't test the html part, so there is surely improvements to do.
Have you tried it like this:
`<ngb-carousel *ngIf="games" [showNavigationArrows]="showNavigationArrows" [showNavigationIndicators]="showNavigationIndicators">
<ng-template ngbSlide style="">
<div class="">
<img src="https://media.services.cinergy.ch/media/box1600/f1323e57a2c4ea79dde779a89d561f85bfbe6bf5.jpg" width="200px" class="img-responsive" style="float:left">
</div>
<div class="">
<img src="https://www.sideshowtoy.com/assets/products/903302-neo/lg/the-matrix-neo-sixth-scale-figure-hot-toys-903302-01.jpg" width="200px" class="img-responsive" style="float:left">
</div>
<div class="">
<img src="http://media.comicbook.com/2018/03/avengers-infinity-war-poster-all-iron-man-version-1096449.jpeg" width="200px" class="img-responsive" style="float:left">
</div>
</ng-template>
</ngb-carousel>
`

Angularjs ng-repeat more data

js app
Now In html I user ng-repeat
<div class="row">
<div ng-repeat="item in Photos" class="col col-33"style="border:none">
<img ng-src="{{item.image}}" imageonload style="width:100px;height:120px;margin-left:auto;margin-right:auto;display:block">
</div>
</div>
My problem is that I have 5 images in list but only 3 of them is on dipslay. Another 2 is not shown on display. How can I solve problem ?
Thanks in advance
May be your images have same url value in the Photos array so you need to use ng-repeat with track by $index like this
<div class="row">
<div ng-repeat="item in Photos track by $index" class="col col-33"style="border:none">
<img ng-src="{{item.image}}" imageonload style="width:100px;height:120px;margin-left:auto;margin-right:auto;display:block">
</div>
</div>
$scope.imagearray = {
'images' : []
};
var i,j,temparray,chunk = 3;
for (i=0,j=$scope. Photos.length; i<j; i+=chunk) {
temparray = $scope. Photos.slice(i,i+chunk);
$scope.imagearray.images.push(temparray);
}
<div ng-repeat="img in imagearray.images">
<span ng-repeat="item in img" ></span>
</div>
Try col-xs-2 instead of col-33:
<div class="row">
<div ng-repeat="item in Photos" class="col col-xs-2">
<img ng-src="{{item.image}}">
</div>
</div>

ng-repeat and $scope issue

I have a page displaying 3 images in a row, using Ng-repeat, but no matter which image I click, I only see the image of the FIRST image displayed in that specific row.
Template:
<div id="galscrolldiv" class="row" ng-repeat="image in images" ng-if="$index % 3 === 0">
<div class="col col-33" ng-if="$index < images.length">
<div ng-click="seeOne(image)">
<img ng-src="{{images[$index].src}}" width="100%" />
</div>
</div>
<div class="col col-33" ng-if="$index + 1 < images.length">
<div ng-click="seeOne(image)">
<img ng-src="{{images[$index + 1].src}}" width="100%" />
</div>
</div>
<div class="col col-33" ng-if="$index + 2 < images.length">
<div ng-click="seeOne(image)">
<img ng-src="{{images[$index + 2].src}}" width="100%" />
</div>
</div>
</div>
ng-click function:
$scope.seeOne = function (image) {
window.localStorage['fbid'] = image.fbid;
$state.go('app.oneimg');
}
$scope.images:
angular.forEach(value, function (value, key) {
if (key == 'photo') {
$scope.images.push({
id: i,
fbid: inventorykey,
src: ("data:image/jpeg;base64," + value)
});
i = i + 1;
}
})
You're repeating <div ng-click="seeOne(image)"> 3 times in this example, where image only refers to the first one of the 3 images you're displaying. If you change that line to match the <img> tag beneath it, you get the result you're looking for. Something like this:
<div id="galscrolldiv" class="row" ng-repeat="image in images" ng-if="$index % 3 === 0">
<div class="col col-33" ng-if="$index < images.length">
<div ng-click="seeOne(images[$index])">
<img ng-src="{{images[$index].src}}" width="100%" />
</div>
</div>
<div class="col col-33" ng-if="$index + 1 < images.length">
<div ng-click="seeOne(images[$index+1])">
<img ng-src="{{images[$index + 1].src}}" width="100%" />
</div>
</div>
<div class="col col-33" ng-if="$index + 2 < images.length">
<div ng-click="seeOne(images[$index+2])">
<img ng-src="{{images[$index + 2].src}}" width="100%" />
</div>
</div>
</div>
{{images[$index].src}} is wrong. use {{image.src}} instead.
The $index will change at each iteration, but there is only one variable. so at the end of the rendering all images will be the same as the refer to the same index. it doesn't matter what was the value when the page is rendered. It matters whats the value at the end of the angular digest phase.
To achieve your use case you need to set and use a local variable into the ng-repeat scope:
<div id="galscrolldiv" class="row" ng-repeat="image in images" ng-if="$index % 3 === 0" ng-init="myIndex = $index">
<div class="col col-33" ng-if="$index < images.length">
<div ng-click="seeOne(image)">
<img ng-src="{{images[myIndex].src}}" width="100%" />
</div>
</div>
Alternative: Put the data in the proper structure (an 2d array) and use nested ng-repeat - makes your life much easier

AngularJS - Showing different divs based on the ng-if result

I've got a simple chat app in AngularJS, and I'm sending a message to the view which is being outputted on the front end like this:
<div id="messages" class="col-xs-12 chat-messages">
<div class="col-xs-12 chat-message" ng-repeat="message in chatMessages">
<div class="you">
<ul class="media-list">
<li class="media">
<div class="media-left">
<div class="media-object img-circle" style="background-image: url( {{message.avatar_url}} )"></div>
</div>
<div class="media-body">
<div class="media-heading text-muted small">
{{message.nickname}}
</div>
<div class="message-content bubble">
{{message.content}}
</div>
</div>
</li>
</ul>
</div>
</div>
</div>
At the moment I am just going through the chatMessages array and outputting them using this div. I have given each message another attribute of kind where I will send to the view different kinds of messages, such as userMe, userOther, global etc. and I will need to use a slightly different HTML markup for each kind of message. I understand that this should be done using ng-if in AngularJS, but I don't quite know how to go about this.
From the view, I will need to output some different HTML depending on the message.kind value.
Any ideas?
If you have several possible div options for each element, I'd use ng-switch, like Tom said in the comments.
The idea is that you switch on the message.kind, or whatever you want to switch on, and have each div as a "Case" for that:
It would look something like this:
<div class="media-body" ng-switch="message.kind">
<div class="media-heading text-muted small" ng-switch-when="1">
{{message.nickname}}
</div>
<div class="message-content" ng-switch-when="2">
{{message.content}}
</div>
<div class="message-content bubble" ng-switch-default>
default text
</div>
</div>
Fiddle
You have two solution to archieve what you want :
<div ng-repeat="msg in messages">
<div ng-if="msg.kind === 'userMe'">userMeMessage</div>
<div ng-if="msg.kind === 'global'">globalMessage</div>
...
</div>
Or this :
<div ng-repeat="msg in messages|filter:{kind:'userMe'}">
UserMe
</div>
<div ng-repeat="msg in messages|filter:{kind:'global'}">
Global
</div>

Categories

Resources