angularjs dynamic select with json array - angularjs

i'm developing an app where i should retreive from the server a JSON array through the http.get method.
The structure of the array is this:
[{
"day": "17/11/2016",
"time": "09:45"
}, {
"day": "17/11/2016",
"time": "16:50"
}, {
"day": "18/11/2016",
"time": "11:25"
}, {
"day": "18/11/2016",
"time": "12:30"
}, {
"day": "21/11/2016",
"time": "16:10"
}, {
"day": "21/11/2016",
"time": "17:25"
}]
From this array i should create a form with two selects where in the first i've days (for example 17/11/2016, 18/11/2016, 21/11/2016) and in the second i should have times "belonging" at days (for example 09:45, 16:50 OR 11:25, 12:30 OR 16:10, 17:25).
I think that i've found the solution at this problem but when i tried to run the project selects are always empty but the console tell me no errors.
This is my code,
HTML:
<html>
<head>
<script data-require="angular.js#1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script src="script.js"></script>
</head>
<body>
<div ng-app="demo">
<div ng-controller="DefaultController as ctrl">
<div class="form-group">
<label>Event Date</label>
<select ng-options="event as event.date for event in ctrl.data.events" ng-model="ctrl.event">
<option value="">Select</option>
</select>
</div>
<div class="form-group">
<label>Event Time</label>
<select ng-options="schedule as schedule.time for schedule in ctrl.data.schedules | filter: { date: ctrl.event.date}" ng-model="ctrl.schedule" ng-disabled="!ctrl.event">
<option value="">Select</option>
</select>
</div>
</div>
</div>
</body>
</html>
JS:
angular
.module('demo', [])
.controller('DefaultController', DefaultController)
.factory('dataService', dataService);
DefaultController.$inject = ['dataService'];
function DefaultController(dataService) {
var vm = this;
getEvents();
function getEvents() {
return dataService.getEvents()
.then(function (data) {
vm.data = data;
return vm.data;
});
}
}
dataService.$inject = ['$http'];
function dataService($http) {
var service = {
getEvents: getEvents
};
return service;
function getEvents() {
var config = {
transformResponse: function (data, headers) {
if(headers("content-type") === "application/json; charset=utf-8" && angular.isString(data)) {
var result = {
events: [],
schedules: []
};
var events = JSON.parse(data);
var dates = [];
for (var i = 0; i < events.length; i++) {
if (dates.indexOf(events[i].day) === -1) {
var date = events[i].day;
dates.push(date);
result.events.push({
date: date
});
}
result.schedules.push({
date: events[i].day,
time: events[i].time
});
}
return result;
} else {
return data;
}
}
};
return $http.get('events.json', config)
.then(getEventsCompleted)
.catch(getEventsFailed);
function getEventsCompleted(response) {
return response.data;
}
function getEventsFailed(error) {
console.error(error);
}
}
}
Can someone help me?
Than'ks

Related

Controlling ng-repeat iterations

HTML :
<div ng-repeat="data in $ctrl.list">
<div ng-init="$ctrl.applyAction(data)">
<h4>{{data.name}}</h4>
<ul ng-if="data.steps">
<li ng-repeat="step in data.steps">{{step.name}}</li>
</ul>
</div>
</div>
Controller :
$onInit() {
this.list = [{
name: "First Obj"
}, {
name: "Second Obj"
}, {
name: "Third Obj"
}, {
name: "Fourth Obj"
}];
}
applyAction(data) {
this.someHttpService.getResponse(data).then(function(success) {
data.reqForSecondServiceCall = success.data;
this.secondServiceCall(data);
}, function(error) {
// console.log(error);
});
}
secondServiceCall(data) {
this.someHttpService.getSecondServiceResponse(data).then(function(success) {
data.status = success.data;
}, function(error) {
// console.log(error);
});
}
Currently ng-repeat will be iterating through the list object irrespective of the service calls made on each object (asynchronous).
And the desired functionality is to render the current object only when the applyActions method is completed on previous object.
One solution is to queue the calls in an event queue and then invoke the events one by one when previous call is completed
angular.module('myApp',[]).controller('myCtrl', function($scope, $http, $timeout){
$scope.title = 'welcome';
$scope.finishedEvent = '';
$scope.eventQueue = [];
$scope.list = [{
name: "First Obj"
}, {
name: "Second Obj"
}, {
name: "Third Obj"
}, {
name: "Fourth Obj"
}];
$scope.applyAction = function(data, index) {
//declare the event
var event = function(){
var testApi = "https://jsonplaceholder.typicode.com/posts";
$http.get(testApi).then(function(response) {
data.steps = response.data.slice(0,2);
$scope.finishedEvent = data.name;
}, function(error) {
console.log(error);
});
};
if(index == 0){
event();
}else{
$scope.eventQueue.push(event);
}
};
$scope.$watch('finishedEvent', function(){
if($scope.eventQueue.length > 0){
$timeout(function(){
console.log($scope.finishedEvent + '- loaded')
var event = $scope.eventQueue[0];
$scope.eventQueue.splice(0, 1); //remove current event from queue
event();
}, 1000);
}
});
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<body ng-app="myApp" ng-controller="myCtrl">
<h1>{{title}}</h1>
<div ng-repeat="data in list">
<div ng-init="applyAction(data, $index)">
<h4>{{data.name}}</h4>
<ul ng-if="data.steps">
<li ng-repeat="step in data.steps">{{step.title}}</li>
</ul>
</div>
</div>
</body>
NOTE 1: I used a dummie api just to have live data
NOTE 2: Remove the $timeout, only added it to make the example clear
Here's a plunker with the example

Filtering specific data from a group of data in angularjs

I want to filter only specific data in angularjs.
here is my object,
$scope.studyTeamObj;
In this object,I have object like this
{"Study_Team": [
{
"designation": {
"Emp_Name": "mdrf",
"Emp_Id": 2,
"Designation": "Research Dietitian",
"DesignationID": 20
}
}
]
}
I want to filter like this.only two datas are enough.How can I do?
{
"Study_Team":[
{
"Emp_Id":1,
"DesignationID":20,
}
]
}
I presume you need an Angular filter without modifying the original object:
var angularApp = angular.module("app", []);
angularApp.filter("studyTeam", function(){
return function(obj){
var studyTeamArr = obj.Study_Team;
return studyTeamArr.map(function(obj){
var desig = angular.copy(obj.designation);
delete desig.Emp_Name;
delete desig.Designation;
return desig;
});
} });
angularApp.controller("angCtrl", function($scope, $filter){
$scope.studyTeamObj = {"Study_Team": [
{
"designation": {
"Emp_Name": "mdrf",
"Emp_Id": 2,
"Designation": "Research Dietitian",
"DesignationID": 20
}
}
]
};
console.log( JSON.stringify( $filter('studyTeam')($scope.studyTeamObj)) );
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="angCtrl">
</div>
</div>

AngularJS filter array of objects, including nested array, with value from <input>

I have such array of objects:
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
And I have tried below AngularJS code for searching:
$scope.searching = '';
$scope.producers = [];
$scope.models = [];
$scope.searchCar = function() {
$scope.producers = $filter('filter')(cars, function(value) {
return value.carMake === $scope.searching;
});
$scope.models = $filter('filter')(cars, function(value) {
return angular.forEach(value.models, function(model) {
return model === $scope.searching;
});
});
};
Inside HTML I have:
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers">{{producer}}</li>
</ul>
<ul>
<li ng-repeat="model in models">{{model}}</li>
</ul>
My code doesn't work as I expected - it only outputs whole cars Array element. For example, when I type "Audi" i got whole "Audi object", although I want separately results for car producers and/or car models that match pattern inside <input>.
I want searching to work like, when I type "Au" then I will see "Audi" in first list and "Auris" in the second. So searching should work as well for cars.carMake as for cars.models[] and present result in both lists (first/left for car producers and second/right for car models).
I'd suggest you to store the items in separated arrays, then use the filter in view:
(function() {
angular
.module("app", [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope'];
function MainCtrl($scope) {
$scope.sensitiveCompare = sensitiveCompare;
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
$scope.producers = cars.map(function(car) {
return car.carMake;
});
$scope.models = [];
cars.forEach(function(car) {
$scope.models = $scope.models.concat(car.models);
});
function sensitiveCompare(input, search) {
return ('' + input).indexOf('' + search) > -1;
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
</head>
<body ng-controller="MainCtrl">
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers | filter: searching: sensitiveCompare" ng-bind="producer"></li>
</ul>
<ul>
<li ng-repeat="model in models | filter: searching: sensitiveCompare" ng-bind="model"></li>
</ul>
</body>
</html>
EDIT:
If you really want to create your custom function for this, check this:
(function() {
angular
.module("app", [])
.controller('MainCtrl', MainCtrl);
MainCtrl.$inject = ['$scope', '$filter'];
function MainCtrl($scope, $filter) {
$scope.searchCar = searchCar;
var cars = [
{
"carMake":"Audi",
"models":[
"A4",
"A6",
"R8"
]
},
{
"carMake":"BMW",
"models":[
"3er",
"X3",
"i8",
"7er"
]
},
{
"carMake":"Toyota",
"models":[
"Corolla",
"Auris",
"Yaris",
"Gt86",
"Rav4"
]
}
];
$scope.producers = [];
$scope.models = [];
function searchCar() {
$scope.producers = $filter('filter')(cars, function(car) {
return car.carMake.indexOf($scope.searching) !== -1;
});
$filter('filter')(cars, function(car) {
$scope.models = car.models.filter(function(model) {
return model.indexOf($scope.searching) !== -1;
})
});
}
}
})();
<!DOCTYPE html>
<html ng-app="app">
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.8/angular.min.js"></script>
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
</head>
<body ng-controller="MainCtrl">
<label>What do you want to find?
<input type="text" ng-model="searching" ng-change="searchCar()" placeholder="Search...">
</label>
<ul>
<li ng-repeat="producer in producers" ng-bind="producer.carMake"></li>
</ul>
<ul>
<li ng-repeat="model in models" ng-bind="model"></li>
</ul>
</body>
</html>

Retrieve specific data within ng-repeat loop angularjs

I'd like to retrieve specific data within a JSON file within an ng-repeat loop, My code is as follows thus far, and it works correctly bringing in the correct low resolution url of the image. I want to display the first comment corresponding to this image from a specific user below it in the <p> tag, ie I want the the first "text" value always from the username "tellasaur". Not sure how to bring that in, could I have some help? thanks!
NG-REPEAT LOOP
<li ng-repeat="p in pics">
<img ng-src="{{p.images.low_resolution.url}}" />
<p></p>
</li>
CONTROLLER
app.controller('ShowImages', function($scope, InstagramAPI){
$scope.layout = 'grid';
$scope.data = {};
$scope.pics = [];
InstagramAPI.fetchPhotos(function(data){
$scope.pics = data;
console.log(data)
});
});
JSON
"images":{
"low_resolution":{
"url":"https:\/\/scontent.cdninstagram.com\/hphotos-xaf1\/t51.2885-15\/s320x320\/e15\/11243658_841091872640638_1858051687_n.jpg",
"width":320,
"height":320
},
},
"comments":{
"count":38,
"data":[
{
"created_time":"1436314585",
"text":"Living on a lake #amarie4107",
"from":{
"username":"tellasaur",
"profile_picture":"https:\/\/igcdn-photos-b-a.akamaihd.net\/hphotos-ak-xfp1\/t51.2885-19\/11142181_1606991566225969_1204610350_a.jpg",
"id":"174270894",
"full_name":"kristella"
},
"id":"1024203434844916571"
},
{
"created_time":"1436317671",
"text":"Wow",
"from":{
"username":"sbcarol2002",
"profile_picture":"https:\/\/igcdn-photos-b-a.akamaihd.net\/hphotos-ak-xfp1\/t51.2885-19\/10707061_359756607505353_826681437_a.jpg",
"id":"1280059782",
"full_name":"Susan Long"
},
"id":"1024229322726738700"
},
{
"created_time":"1436320519",
"text":"\ud83d\udc93 dreamyy",
"from":{
"username":"veekster",
"profile_picture":"https:\/\/igcdn-photos-h-a.akamaihd.net\/hphotos-ak-xtf1\/t51.2885-19\/11117059_1743047859255223_204225114_a.jpg",
"id":"31179150",
"full_name":"Victoria Wright"
},
"id":"1024253210688915485"
}
]
}
Here's one way to do it using a filter.
angular.module('app',[])
.filter('getFirstCommentFrom',function(){
return function(arr, user){
for(var i=0;i<arr.length;i++)
{
if(arr[i].from.username==user)
return arr[i].text;
}
return '';
}
})
.controller('TestCtrl', function($scope){
$scope.pics = [
{ "images":{
"low_resolution":{
"url":"https:\/\/scontent.cdninstagram.com\/hphotos-xaf1\/t51.2885-15\/s320x320\/e15\/11243658_841091872640638_1858051687_n.jpg",
"width":320,
"height":320
},
},
"comments":{
"count":38,
"data":[
{
"created_time":"1436314585",
"text":"Living on a lake #amarie4107",
"from":{
"username":"tellasaur",
"profile_picture":"https:\/\/igcdn-photos-b-a.akamaihd.net\/hphotos-ak-xfp1\/t51.2885-19\/11142181_1606991566225969_1204610350_a.jpg",
"id":"174270894",
"full_name":"kristella"
},
"id":"1024203434844916571"
},
{
"created_time":"1436317671",
"text":"Wow",
"from":{
"username":"sbcarol2002",
"profile_picture":"https:\/\/igcdn-photos-b-a.akamaihd.net\/hphotos-ak-xfp1\/t51.2885-19\/10707061_359756607505353_826681437_a.jpg",
"id":"1280059782",
"full_name":"Susan Long"
},
"id":"1024229322726738700"
},
{
"created_time":"1436320519",
"text":"\ud83d\udc93 dreamyy",
"from":{
"username":"veekster",
"profile_picture":"https:\/\/igcdn-photos-h-a.akamaihd.net\/hphotos-ak-xtf1\/t51.2885-19\/11117059_1743047859255223_204225114_a.jpg",
"id":"31179150",
"full_name":"Victoria Wright"
},
"id":"1024253210688915485"
}
]
}
}
]
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
<div ng-app="app" ng-controller="TestCtrl">
<li ng-repeat="p in pics">
<img ng-src="{{p.images.low_resolution.url}}" />
{{p.comments.data|getFirstCommentFrom:'tellasaur'}}
<p></p>
</li>
</div>

Multiple custom filters in angular.js

I have a multi check box application which requires me to have multiple filters. I have been unable to use multiple filters even if I try to hard code an array to filter on. Here is an example I have created to try to make this work.
Working Example
HTML MARKUP:
<body ng-app="app">
<div ng-controller="MainCtrl">
<div ng-repeat="item in data.sessions | IndustryFilter : data.sessions.industry ">
{{item.id}}
</div>
</div>
Javascript
var app = angular.module("app", [])
.controller("MainCtrl", function ($scope, MatchedFilterList) {
$scope.data = {"sessions": [{
"id": "a093000000Vhzg7AAB",
"industry": ["Automovtive"],
"sessionName": "Keynote",
},
{
"id": "a093000000zg7AAB",
"industry": ["Automovtive", "Retail"],
"sessionName": "Keynote2",
},
{
"id": "a093er000f00zg7AAB",
"industry": ["Automovtive", "Retail", "Consumer Goods"],
"sessionName": "Keynote3",
}
]};
}).filter("IndustryFilter", function (MatchedFilterList) {
return function () {
var filtered = [];
angular.forEach(MatchedFilterList.industry, function (item) {
filtered.push(item);
});
console.log("Filter: Filter " + filtered)
return filtered;
};
})
.factory("MatchedFilterList", function(){
var matchedFilterList = {};
matchedFilterList.industry = {
"Automotive": "Automotive",
"Retail" : "Retail"
};
return matchedFilterList;
});

Resources