Search code examples
angularjsangularjs-ng-repeatflickr

Show clicked image from flickr with tags and comments AngularJS


I have to make app for listing recent photos from Flickr with option when click on any image to show that image with tags and comments it contains.

I've made this:

core.module.js

(function () {
'use strict';

angular.module('flickrApp.core', ['ui.router', 'ngResource']);

})();

core.factory.js

(function () {
'use strict';

angular
    .module('flickrApp.core')
    .factory('flickrImgs', flickrImgs);

flickrImgs.$inject = ['$http'];

function flickrImgs($http) {

    var url = 'https://api.flickr.com/services/rest/?method=flickr.photos.getRecent&api_key=415028ef16a31ed8f70f9dc3e90964d1&extras=url_q,url_o,tags&format=json&nojsoncallback=1';

    var photos;

    var factory = {
        getPhotos: getPhotos
    };

    return factory;

    function getPhotos() {
        return $http.get(url).then(function (response) {
            factory.photos = response.data.photos.photo;
        });
    }
};
})();

core.controller.js

(function () {
'use strict';

angular
    .module('flickrApp.core')
    .controller('flickrController', flickrController);

flickrController.$inject = ['flickrImgs', '$location', '$http'];

function flickrController(flickrImgs, $location, $http) {

    var fc = this;

    fc.showImg = function (id) {
        $location.path("/photos/" + id);
        console.log(id);
    };

    flickrImgs.getPhotos().then(function () {
        fc.photos = flickrImgs.photos;
    });

}

})();

core.router.js

(function () {
'use strict';

angular
    .module('flickrApp.core')
    .config(config);

config.$inject = ['$stateProvider', '$urlRouterProvider'];

function config($stateProvider, $urlRouterProvider) {

    $urlRouterProvider.otherwise('/home');

    $stateProvider
        .state('main', {
            abstract: true,
            views: {
                'header': {
                    templateUrl: 'app/components/core/header.html'
                }
            }
        })
        .state('main.home', {
            url: '/home',
            views: {
                'content@': {
                    templateUrl: 'app/components/core/home.html',
                    controller: 'flickrController',
                    controllerAs: 'fc'
                }
            }
        })
        .state('main.singleImg', {
            url: '/photos/:id',
            views: {
                'content@': {
                    templateUrl: 'app/components/core/single-img.html',
                    controller: 'flickrController',
                    controllerAs: 'fc'
                }
            }
        });

    newPhoto.$inject = ['$stateParams', 'flickrImgs'];

    function newPhoto($stateParams, flickrImgs) {
        return flickrImgs.get({
            id: $stateParams.id
        }).$promise;
    }

}

})();

home.html

<div class="row col-sm-12 col-md-10 col-md-offset-1">
<div ng-repeat="photo in fc.photos | limitTo:16" class="col-sm-12 col-md-3">
    <a href ng-click="fc.showImg(photo.id)">
        <img class="thumbnail" ng-src="{{photo.url_q}}" width="100%">
    </a>
</div>
</div>

single-img.html

<div class="row col-sm-12 col-md-10 col-md-offset-1">
<div ng-repeat="photo in fc.photos | filter : {id: photo.id} | limitTo: 1" class="col-sm-12 col-md-10 col-md-offset-1">
    <a href ng-click="fc.showImg(photo.id)">
        <img class="thumbnail" ng-src="{{photo.url_o}}" width="100%">
    </a>
    <div>Tags:
        <button class="btn-primary">
            {{photo.tags}}
        </button>
    </div>
    <div>Comments:
        <div>
            {{photo.comments}}
        </div>
    </div>
</div>
</div>

When I click on image listed on home page, I want to pass that image to single-img.html template and I get image id in url, but I don't know how to pass it to html.

Any help would be appreciated.


Solution

  • You are missing ui-sref in in home.html

    <div class="row col-sm-12 col-md-10 col-md-offset-1">
    <div ng-repeat="photo in fc.photos | limitTo:16" class="col-sm-12 col-md-3">
        <a ui-sref="main.singleImg({id: photo.id})">
            <img class="thumbnail" ng-src="{{photo.url_q}}" width="100%">
        </a>
    </div>
    </div>
    

    // Updated flickrImgs factory method

    function getPhotos() {
        var deferred = $q.defer();
    
        if (factory.photos) {
            deferred.resolve(factory.photos);
        } else {
            $http.get(url).then(function(response) {
                factory.photos = response.data.photos.photo;
    
                deferred.resolve(factory.photos);
            });
        }
    
        return deferred.promise;
    }
    

    // single image state with new controller

    .state('main.singleImg', {
        url: '/photos/:id',
        views: {
            'content@': {
                templateUrl: 'app/components/core/single-img.html',
                controller: 'singleImgController',
                controllerAs: 'sic'
            }
        }
    });
    

    // New Controller

    angular
        .module('flickrApp.core')
        .controller('singleImgController', singleImgController);
    
    singleImgController.$inject = ['$stateParams', 'flickrImgs'];
    
    function singleImgController($stateParams, flickrImgs) {
        var vm = this;
    
        flickrImgs.getPhotos()
        .then(function(photos) {
            angular.forEach(photos, function(photo) {
                if(photo.id == $stateParams.id) {
                    vm.photo = photo;
                }
            })
        });
    }
    

    // New single-img.html

    <div class="row col-sm-12 col-md-8 col-md-offset-2">
    <img class="thumbnail" ng-src="{{sic.photo.url_o}}" width="100%">
    <div>Tags:
        <div class="btn-primary">
            {{sic.photo.tags}}
        </div>
    </div>
    <div>Comments:
        <div>
            {{sic.photo.comments}}
        </div>
    </div>
    </div>
    

    Hope this helps.