Reputation: 4343
I am writing an angular website, but I have the following problem. I have 2 data arrays that I get from my json files.
I use an ng-repeat to go over my projects in my html file, and I use another ng-repeat to go over my projects.languages. Now what I want to do is to make it that for every language I find I am going to search in the languages data and get the other information.
How can I easly get the language in the ng-repeat, I need to also calculate in that the data maybe not avaible yet, because I get the json data async.
This is the code I have right now:
<div class="container-fluid contentcontainer">
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<div class="languageoverlay">
<span ng-repeat="language in projects[$index].languages">
<img ng-src="img/languages/android.png" ng-alt="{{language}}" />
<font ng-show="!$last">+</font>
</span>
</div>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
</div>
<!--this is just to try, don't need to use this-->
<h1>{{getLanguage("CSharp")}}</h1>
App.js
app.service('projectService', ['$http', '$q', function($http, $q) {
var projectsDeferred = $q.defer();
var languagesDeferred = $q.defer();
$http({
method: 'POST',
url: 'json/projects.json',
cache: true
}).then(function(data) {
projectsDeferred.resolve(data.data.projects);
});
$http({
method: 'POST',
url: 'json/projects.json',
cache: true
}).then(function(data) {
languagesDeferred.resolve(data.data.languages);
});
this.getProjects = function(){
return projectsDeferred.promise;
};
this.getLanguages = function(){
return languagesDeferred.promise;
};
}]);
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projects = {};
$scope.languages = {};
var promise = projectService.getProjects();
promise.then(function(data) {
$scope.projects = data;
});
var promise = projectService.getLanguages();
promise.then(function(data) {
$scope.languages = data;
});
// This was a try, don't need to use this
$scope.getLanguage = function(name) {
array.forEach(function(element) {
if (element.name == name) {
$scope.push(element);
}
}, $scope.languages);
};
}]);
languages.json
{
"result":"SUCCESS",
"resultMessage":"",
"languages":[
{
"name":"CSharp",
"FullName":"C#",
"img":"img/languages/csharp.png"
},
{
"name":"Android",
"FullName":"Android",
"img":"img/languages/android.png"
},
{
"name":"VisualStudio",
"FullName":"Visual Studio",
"img":"img/languages/visualstudio.png"
}
]
}
projects.json
{
"result":"SUCCESS",
"resultMessage":"",
"projects":[
{
"name":"Test1",
"img":"img/projects/photo-1453060113865-968cea1ad53a.jpg",
"languages":["Android"]
},
{
"name":"Test2",
"img":"img/projects/photo-1454165205744-3b78555e5572.jpg",
"languages":["Android"]
},
{
"name":"Test3",
"img":"img/projects/photo-1457305237443-44c3d5a30b89.jpg",
"languages":["CSharp","VisualStudio"]
},
{
"name":"Test4",
"img":"img/projects/photo-1457612928689-a1ab27da0dad.jpg",
"languages":["CSharp","VisualStudio"]
}
]
}
Upvotes: 0
Views: 80
Reputation: 4343
I really loved your awnser, but I made another approach with directives. I tested your awnser and it looks like a correct awnser.
This is what I did:
projects-directive.html
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<languages languagenames="project.languages"></languages>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
languages-directive.html
<div class="languageoverlay">
<span ng-repeat="language in languages">
<img ng-src="{{language.img}}" ng-alt="{{language.FullName}}" />
<font ng-show="!$last">+</font>
</span>
</div>
app.js
app.service('projectService', ['$http', '$filter', function($http, $filter) {
this.getLanguages = function() {
return $http({
method: 'GET',
url: 'json/languages.json',
cache: true
});
}
this.getProjects = function(){
return $http({
method: 'GET',
url: 'json/projects.json',
cache: true
})
};
}]);
app.directive('projects', ['projectService', function(projectService) {
return {
restrict: 'E',
templateUrl: "directives/projects-directive.html",
scope: {
limitto: "=?"
},
controller: function($scope)
{
projectService.getProjects().then(function(response) {
projects = response.data.projects;
if (angular.isDefined($scope.limitto))
{
$scope.projects = projects.slice(0, $scope.limitto);
} else {
$scope.projects = projects;
}
});
}
}
}]);
app.directive('languages', ['projectService', '$filter', function(projectService, $filter) {
return {
restrict: 'E',
templateUrl: "directives/languages-directive.html",
scope: {
languagenames: "="
},
controller: function($scope)
{
projectService.getLanguages().then(function(response) {
$scope.languages = $scope.languagenames.map(function (l) {
var matchLangs = $filter('filter')(response.data.languages, { name: l });
if (matchLangs.length) {
return matchLangs[0];
} else {
return { FullName: l };
}
});
});
}
}
}]);
app.controller('PortfolioController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projectlimit = 4;
}]);
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
}]);
How to call the directive:
<projects></projects>
and if you want to limit it, you can add parameter:
<projects limitto="projectlimit"></projects>
Upvotes: 1
Reputation: 134
Easy piece:
First don't use $q just use $http
app.service('projectService', ['$http', '$filter', function($http, $filter) {
function callLanguages(languages) {
return $http({
method: 'GET',
url: 'json/projects.json',
cache: true
}).then(function (response) {
return buildProjectWithLanguages(response.data.projects, languages);
});
}
function buildProjectWithLanguages (projects, languages) {
return projects.map(function (p) {
var langs = p.languages.map(function (l) {
var matchLangs = $filter('filter')(languages, { name: l });
if (matchLangs.length) {
return matchLangs[0];
} else {
return { FullName: l };
}
});
p.languages = langs;
return p;
});
}
this.getProjects = function(){
return $http({
method: 'GET',
url: 'json/languages.json',
cache: true
}).then(function(response) {
return callLanguages(response.data.languages);
});
};
}]);
then simplify your controller
app.controller('ProjectsController', ['$scope', 'projectService', function($scope, projectService) {
$scope.projects = [];
projectService.getProjects(function (projects) {
$scope.projects = projects;
});
}]);
and finally change your html to this:
<div class="container-fluid contentcontainer">
<div class="row">
<div class="col-xs-6 col-md-3" ng-repeat="project in projects">
<a href="#/project/{{$index}}" class="thumbnail">
<img ng-src="{{project.img}}" ng-alt="{{project.name}}" />
<div class="caption">
<div class="languageoverlay">
<span ng-repeat="language in project.languages">
<img ng-src="{{language.img}}" ng-alt="{{language.FullName}}" />
<font ng-show="!$last">+</font>
</span>
</div>
<h3>{{project.name}}</h3>
</div>
</a>
</div>
</div>
</div>
Upvotes: 1