Sort a list of two different objects with one common property - javascript

I have two lists that are coming from an API that represent two different classes. I want to display the two lists according to their proprieties in one general list where the elements are sorted by their date.
I need to separate the two lists because the proprieties to display are different and they only share the Date.
I manage to display the two list separately but cannot merge the two... Does anyone have an idea on that? Thank you very much.
here is the .js and view:
.js:
function activityController($http) {
var vm = this;
vm.race= [];
vm.try= [];
vm.errorMessage = "";
vm.isBusy = true;
$http.get("/api/race")
.then(function (response) {
//Sucess
angular.copy(response.data, vm.race);
}, function (error) {
//Failure
vm.errorMessage = "Failed to load the data" + error;
})
$http.get("/api/try")
.then(function (response) {
//Sucess
angular.copy(response.data, vm.try);
}, function (error) {
//Failure
vm.errorMessage = "Failed to load the data" + error;
})
.finally(function () {
vm.isBusy = false;
});
}
View :
<div class="col-md-offset-7">
<div class="text-danger" ng-show="vm.errorMessage">{{ vm.errorMessage}}</div>
<wait-cursor ng-show="vm.isBusy"></wait-cursor>
<ul class="well" ng-repeat="activities in vm.race| orderBy: 'date':true">
<li> {{activities.title}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.time}}</li>
</ul>
<ul class="well" ng-repeat="activities in vm.try| orderBy: 'date':true">
<li> {{activities.person}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.type}}</li>
</ul>

The way I would do it is:
<ul class="well" ng-repeat="activities in vm.getRacesAndTrys()| orderBy: 'date':true">
<li> {{activities.title}}</li>
<li>Date : {{activities.date | date :'dd-MM-yyyy'}}</li>
<li>Temps : {{activities.time}}</li>
</ul>
With a function in your vm:
vm.getRacesAndTrys = function() {
var result = [];
for (var i = 0; i < vm.try.length; i++) {
var item = vm.try[i];
result.push({
title: item.person,
date: item.date,
time: item.type
});
}
for (var i = 0; i < vm.race.length; i++) {
result.push(vm.race[i]);
}
return result;
}
This will create a combined array and also convert all the try objects so that their fields match that of the race objects.

Related

ngFilter equals with 2 var in angular

I have a little problem, I would like to do a equals with 2 var in ngFilter. I try lot of combinaison, but it doesn't work...
I get the first var here, in $routeParams
function ANNAnnonceListe(DBManager, $routeParams) {
var ici = this;
this.annonces_ar = [];
this.idLieu = $routeParams.idLieu;
DBManager.all('ANNAnnonce')
.then(function (annonces) {
console.log(annonces);
ici.annonces_ar = annonces;
})
.catch(function (error) {
console.log(error)
});
}
the second here :
<div ng-repeat="(key, value) in vm.annonces_ar | filter: {value.id : vm.idLieu_nb} ">
{{value.nom_str}}
{{value.idLieu_nb}}
</div>
i would like this equality (vm.idLieu = value.id_nb) and display if is true
Thanks.
It should be property name directly id_nb instead of value.id. Also have : true parameter at the end of your filter to perform exact check, inspite of contains check.
<div ng-repeat="(key, value) in vm.annonces_ar | filter: { idLieu_nb : vm.idLieu}: true ">
{{value.nom_str}}
{{value.idLieu_nb}}
</div>

Angularjs search product by price (from price to price)

I'm trying to add filter for searching the product by from price to price. I have following array in json format as $scope.products in the controller.
[
{"product_id":"1","product_price":"185"},
{"product_id":"2","product_price":"45"},
{"product_id":"3","product_price":"123"},
{"product_id":"4","product_price":"23"},
{"product_id":"5","product_price":"776"}
]
And below is the loop in html
<ul class="items">
<li ng-repeat="product in products | filter:{product_name: findname} | sizeFilter:(size_arr|filter:{on:true})" >
<strong>{{product.product_name | CapsFirst}}</strong>
<strong>({{product.product_category}})</strong>
<strong>({{product.product_size}})</strong>
<strong>({{product.product_color}})</strong>
</li>
</ul>
In the view I want to add two input fields for searching the products by price.
<input type="number" ng-model="from_price" />
<input type="number" ng-model="to_price" />
Can anyone guide me that I can develop in proper way. I've searched about it but couldn't found a tutorial, I'm not expertise in angularjs. Thank You...
Here's an example on plunkr of what you've been asking for. I have added a product name in order to distinguish them, try it.
https://plnkr.co/edit/NKos4x9eeB5dZQaypurg?p=preview
app.filter('sizeFilter', [function() {
return function(values, config) {
if (config.enabled) {
var filterResult = [];
angular.forEach(values, function(value) {
if (value.product_price >= config.from_price && value.product_price <= config.to_price) {
filterResult.push(value);
};
});
return filterResult;
}
return values;
}
}]);
In HTML
<li ng-repeat="product in products |rangePrice:
{'toPrice':to_price,'fromPrice':from_price}">
In JavaScript
app.filter('rangePrice', function() {
return function( items, rangePrice ) {
var filteredValue= [];
var toPrice= parseInt(rangePrice.toPrice);
var fromPrice= parseInt(rangePrice.fromPrice);
angular.forEach(items, function(item) {
if( item.product_price>= toPrice&& item.product_price<= toPrice) {
filteredValue.push(item);
}
});
return filteredValue;
};
});

How to render data with Handlebars and jQuery

I have this html where I need to render the data
default.hbs
<div class="chart-container" data-action="chartContainer">
<ul>
<li class="department">
<h3>Enterprise</h3>
<ul class="sections">
// HERE I NEED TO RENDER THE DATA IN AN <li> TAG
</ul>
</li>
</ul>
</div>
and here is the code
APP.chartContainer = (function () {
var Handlebars = window.Handlebars;
var bindEventsToUI = function () {
$.getJSON('maindata.json')
.done(function(data) {
localStorage.setItem('jsonData', JSON.stringify(data));
}).fail(function(err) {
console.log(err);
});
var chartContainerTemplate = $(".chart-container").html();
var theTemplate = Handlebars.compile(chartContainerTemplate);
var getData = localStorage.getItem('jsonData');
var iterateObj = $.each(JSON.parse(getData), function(key, val) {
return val;
});
var theCompiledHtml = theTemplate(iterateObj[0].enterprise);
$(".sections").append(theCompiledHtml);
};
var init = function (element) {
bindEventsToUI();
};
/**
* interfaces to public functions
*/
return {
init: init
};
}());
the function iterateObj returns this
[
{
"enterprise":[
{
"id":"10",
"name":"Hellen Quesada",
"role":"Principal Software Engineer"
},
{
"id":"11",
"name":"Jonathan Chavez",
"role":"Principal Creative Engineer"
}
]
},
{
"consumer":[
{
"id":"18",
"name":"Helga Martinez",
"role":"Production Manager"
},
{
"id":"19",
"name":"Leroy Bernard",
"role":"Sr. Software Engineer"
}
]
}
]
but all I need to render for now is the enterprise part of the data, that is why in my function I am doing iterateObj.[0].enterprise but I am not getting anything in the DOM yet, how do I iterate properly in the over the object in order to get the rendering of the data I need?
What am I missing ?
The template needs to be a script not html. The script can contain the needed html though.
<script id="foo" type="text/x-handlebars-template">
<div class="chart-container" data-action="chartContainer">
<ul>
<li class="department">
<h3>Enterprise</h3>
<ul class="sections">
//Not really sure what you want here
//But access the data like this
<li>{{enterprise.id}}</li>
</ul>
</li>
</ul>
</div>
</script>
Then you compile the template (ie the script):
//var chartContainerTemplate = $(".chart-container").html();
//rename the script to a better id
var chartContainerTemplate = $("#foo").html();
Lastly I would highly suggest reading the docs. There are ways of looping and accessing data. The above template is very basic.

Variable being overriden in for loop

For each event, their is a different location. However when it is displayed on the UI all locations have been overridden by the last API call. How can I stop this from happening?
$scope.eventLoc = '';
API.get({entity: 'organisation', entity_id: oid, property: 'campaign', property_id:cid, property2:'events'}, function(resp) {
$scope.orgEvents = resp.data;
for (i in resp.data) {
ceid = resp.data[i].CampaignEventID;
lid = resp.data[i].LocationID;
API.get({entity: 'location', entity_id: lid}, function(respLocation){
$scope.eventLoc = respLocation.data;
})
}
});
<li ng-repeat="event in orgEvents track by $index">
<h2>{{event.Name}}</h2>
{{eventLoc.Address1}}
</li>
Simply change your code to something like this:
//$scope.eventLoc = ''; //this can be removed
API.get({entity: 'organisation', entity_id: oid, property: 'campaign', property_id:cid, property2:'events'}, function(resp) {
$scope.orgEvents = resp.data;
angular.forEach($scope.orgEvents, function(orgEvent) {
//ceid = orgEvent.CampaignEventID; //this is not being used?
lid = orgEvent.LocationID;
API.get({entity: 'location', entity_id: lid}, function(respLocation){
orgEvent.eventLoc = respLocation.data;
});
});
});
<li ng-repeat="event in orgEvents track by $index">
<h2>{{event.Name}}</h2>
{{event.eventLoc.Address1}}
</li>

Filter ng-repeat with dropdown without duplicating the dropdown options

The same way, I can manually do filter: { category : 'Popular'} in ng-repeat, I'd like to be able to do the same thing with the dropdown.
I was able to make the basics work. I have two problems: I don't want the categories to duplicate themselves in the dropdown, I'd like to be able to see everything categorized "Popular" when I select "Popular" in the dropdown.
Here is my HTML:
<div ng-controller="SuperCtrl" class="row">
<ul class="small-12 medium-12 columns">
<select ng-model="find" ng-options="entry.category for entry in parsedEntries"><option value="">Select Category</option></select>.
<li ng-repeat="entry in parsedEntries | filter: find">
<strong>{{ entry.title }} </strong><br>
{{ entry.description }}
</li>
</ul></div>
Here is the controller:
app.controller('SuperCtrl', ['$scope', '$http', function($scope,$http) {
var url = 'https://spreadsheets.google.com/feeds/list/1lZWwacSVxTD_ciOsuNsrzeMTNAl0Dj8SOrbaMqPKM7U/od6/public/values?alt=json'
var parse = function(entry) {
var category = entry['gsx$category']['$t'];
var description = entry['gsx$description']['$t'];
var title = entry['gsx$title']['$t'];
return {
category: category,
description: description,
title: title
};
}
$http.get(url)
.success(function(response) {
var entries = response['feed']['entry'];
$scope.parsedEntries = [];
for (key in entries) {
var content = entries[key];
$scope.parsedEntries.push(parse(content));
}
});
}]);
Got it working as you want with :
<select ng-model="find" ng-options="entry.category as entry.category for entry in parsedEntries | unique: 'category'">
The unique filter is from angular-filter. It requires to add 'angular.filter' you to your modules dependencies:
var app = angular.module('myApp', ['angular.filter']);
See fiddle
NB: Not a problem by itself but I took the <select> element out of the <ul> one.
Just put unique categories into in a string array called categories, sort the array, and display it with ng-options:
<select ng-model="find" ng-options="category as category for category in categories"><option value="">Select Category</option></select>.
Append this to your code after your parse function, and delete the $http.get you had. This defines a contains function and builds the array at the same time the objects come back:
function contains(a, obj) {
for (var i = 0; i < a.length; i++) {
if (a[i] === obj) {
return true;
}
}
return false;
};
$http.get(url)
.success(function(response) {
var entries = response['feed']['entry'];
$scope.parsedEntries = [];
$scope.categories = [];
for (key in entries) {
var content = entries[key];
var obj = parse(content);
$scope.parsedEntries.push(obj);
if (!contains($scope.categories, obj.category))
{
$scope.categories.push(obj.category);
}
}
$scope.categories.sort();
})

Categories