ng-repeat is commened in the browser Element section in AngularJs? - angularjs

I have to call the firebase function for get the sellerProducts but in my case function is called peoperly and array is display in the element console but ng-repeat data is commented what is the problem in my code?
//FUNCTION FOR GET THE LIST OF PRODUCT'S
$scope.productArray = [];
$scope.getProductData = function() {
firebase.database().ref("sellerProduct").once('value').
then(function(snapshot) {
var value = snapshot.val();
$scope.productArray = objToArray(value);
});
}
$scope.getProductData();
<div class="productInfo w3-col m3 w3-card-4 w3-margin-left"
ng-repeat="list in filtered = (productArray | filter: product) | filter:brandFilter">
</div>

As far as I could suggest it is much better to NOT use ng-filter at all inside a ng-repeat as it will cost you severe performance issue later on.
so instead of doing this:
ng-repeat="list in filtered = (productArray | filter: product) | filter:brandFilter"
just simply use:
ng-repeat="list in productArray"
then in your JS code format the array first the way you wanted it to be displayed, before assigning it to $scope.productArray
.then(function(snapshot)
{
var value = snapshot.val();
// save the original array
$scope.productArrayOrig = angular.copy(objToArray(value));
$scope.productArray = $scope.filterByBrand();
});
});
// then just create a function that filters your projectData by brandFilter
$scope.filterByBrand = function ()
{
var finalData = [];
if ($scope.productArrayOrig)
{
// then loop it
for (var i = 0; i < $scope.productArrayOrig.length; i++)
{
var item = $scope.productArrayOrig[i];
if ($scope.brandFilter == item["brand"])
{
finalData.push(item);
}
}
}
return finalData;
};
hope that helps

Related

knockout push item to non-existing observableArray

From within a viewmodel I'm trying to dynamically push items to an observableArray. The ajax returns the data correctly.
html :
<li class="liTagulTagsChild" data-bind="click:$root.GetEmissions">/li>
javascript:
var TagDetail = function (di_titre, di_diffusion) {
this.di_titre = ko.observable(di_titre);
this.di_diffusion = ko.observable(di_diffusion);
}
var testA = [];
this.test = ko.observableArray(testA);
this.GetEmissions = function (c, event) {
var element = event.target;
var tag_id = element.getAttribute('tag_id');
$.AjaxAntiforgery({
url: 'Emission/GetDetailsByTagID/',
data: {
tag_id: tag_id
},
success: function (result) {
for (var i = 0; i < result.length; i++) {
var tD = new TagDetail(result[i].DI_TITRE, result[i].DI_DIFFUSION);
this.test.push(tD);
}
}
});
}
Problem: From within the GetEmissions function I cannot push items to this.test because this.test is null (not defined).
In other words,
this.test.push(tD);
fails. (null reference or not defined)
A solution anyone ?
In Javascript "this" doesn't mean what you think it means. Check out How to access the correct `this` context inside a callback?

How do you filter an object of objects with unique keys in an angular ng-repeat?

So I am trying to figure out how to fintler an object of objects in a angular ng-repeat.
Data
$scope.data = {key1:value1, key2:value2, key3:value3};
$scope.filterStr = 'ey';
NG-Repeat
<div ng-repeat="(val, key) in data | filter:filterStr"></div>
This obviously does not work as the filter is expecting an array and not an object but I want to know how to do this without converting my data to an array.
I figured it out, I needed to create a custom filter. The below code works great.
Custom Filter
angular.module('ui.global')
.filter('objFilter', function () {
return function (obj, param) {
var newObj = {};
if(param){
for(var key in obj){
if(key.toLowerCase().includes(param.toLowerCase())){
newObj[key] = obj[key];
}
}
} else {
newObj = obj;
}
return newObj;
};
});
Data
$scope.data = {key1:value1, key2:value2, key3:value3};
$scope.filterStr = 'ey';
NG-Repeat
<div ng-repeat="(val, key) in data | objFilter:filterStr"></div>

angular push result to controller

(was not sure what to have as a title, so if you have a better suggestion, feel free to come up with one - I will correct)
I am working on an angular application where I have some menues and a search result list. I also have a document view area.
You can sort of say that the application behaves like an e-mail application.
I have a few controllers:
DateCtrl: creates a list of dates so the users can choose which dates they want to see posts from.
SourceCtrl: Creates a list of sources so the user can choose from which sources he/she wants to see posts from.
ListCtrl: The controller populating the list. The data comes from an elastic search index. The list is updated every 10-30 seconds (trying to find the best interval) by using the $interval service.
What I have tried
Sources: I have tried to make this a filter, but a user clicks two checkboxes the list is not sorted by date, but on which checkbox the user clicked first.
If it is possible to make this work as a filter, I'd rather continue doing that.
The current code is like this, it does not do what I want:
.filter("bureauFilter", function(filterService) {
return function(input) {
var selectedFilter = filterService.getFilters();
if (selectedFilter.length === 0) {
return input;
}
var out = [];
if (selectedFilter) {
for (var f = 0; f < selectedFilter.length; f++) {
for (var i = 0; i < input.length; i++) {
var myDate = input[i]._source.versioncreated;
var changedDate = dateFromString(myDate);
input[i]._source.sort = new Date(changedDate).getTime();
if (input[i]._source.copyrightholder === selectedFilter[f]) {
out.push(input[i]);
}
}
}
// return out;
// we need to sort the out array
var returnArray = out.sort(function(a,b) {
return new Date(b.versioncreated).getTime() - new Date(a.versioncreated).getTime();
});
return returnArray;
} else {
return input;
}
}
})
Date: I have found it in production that this cannot be used as a filter. The list of posts shows the latest 1000 posts, which is only a third of all posts arriving each day. So this has to be changed to a date-search.
I am trying something like this:
.service('elasticService', ['es', 'searchService', function (es, searchService) {
var esSearch = function (searchService) {
if (searchService.field === "versioncreated") {
// doing some code
} else {
// doing some other type of search
}
and a search service:
.service('searchService', function () {
var selectedField = "";
var selectedValue = "";
var setFieldAndValue = function (field, value) {
selectedField = field;
selectedValue = value;
};
var getFieldAndValue = function () {
return {
"field": selectedField,
"value": selectedValue
}
};
return {
setFieldAndValue: setFieldAndValue,
getFieldAndValue: getFieldAndValue
};
})
What I want to achieve is this:
When no dates or sources are clicked the whole list shall be shown.
When Source or Date are clicked it shall get the posts based on these selections.
I cannot use filter on Date as the application receives some 3000 posts a day and so I have to query elastic search to get the posts for the selected date.
Up until now I have put the elastic-search in the listController, but I am now refactoring so the es-search happens in a service. This so the listController will receive the correct post based on the selections the user has done.
Question is: What is the best pattern or method to use when trying to achieve this?
Where your data is coming from is pretty irrelevant, it's for you to do the hook up with your data source.
With regards to how to render a list:
The view would be:
<div ng-controller='MyController as myCtrl'>
<form>
<input name='searchText' ng-model='myCtrl.searchText'>
</form>
<ul>
<li ng-repeat='item in myCtrl.list | filter:myCtrl.searchText' ng-bind='item'></li>
</ul>
<button ng-click='myCtrl.doSomethingOnClick()'>
</div>
controller would be:
myApp.controller('MyController', ['ElasticSearchService',function(ElasticSearchService) {
var self = this;
self.searchText = '';
ElasticSearchService.getInitialList().then(function(list) {
self.list = list;
});
self.doSomethingOnClick = function() {
ElasticSearchService.updateList(self.searchText).then(function(list) {
self.list = list;
});
}
}]);
service would be:
myApp.service('ElasticSearchService', ['$q', function($q) {
var obj = {};
obj.getInitialList = function() {
var defer = $q.defer();
// do some elastic search stuff here
// on success
defer.resolve(esdata);
// on failure
defer.reject();
return defer.promise();
};
obj.updateList = function(param) {
var defer = $q.defer();
// do some elastic search stuff here
// on success
defer.resolve(esdata);
// on failure
defer.reject();
return defer.promise();
};
return obj;
}]);
This code has NOT been tested but gives you an outline of how you should approach this. $q is used because promises allow things to be dealt with asynchronously.

How to fill "ion-checkbox ng-repeat" at the time of page load

What I need to do?
I am trying to load the "ion-checkbox ng-repeat" "onDeviceReady" automatically at the time of page load. Below is the HTML code.
<ion-checkbox ng-repeat="item in devList"
ng-model="item.checked"
ng-checked="item.checked">
{{ item.text }}
</ion-checkbox>
But the "ion-checkbox ng-repeat" is getting loaded only when click event is triggered.
The below is the angular-js code which needs to be triggered automaticlly at the time of page load.
Problem: The data for "ion-checkbox ng-repeat" is not getting filled at the time of page load.
Can anyone help to solve the issue.
angular.module('app', ['ionic'])
.controller('AppCtrl', function($scope) {
$scope.devList = [];
window.addEventListener("deviceready", onDeviceReady, true);
function onDeviceReady() {
var options = new ContactFindOptions();
options.filter = ""; // empty search string returns all contacts
options.multiple = true; // return multiple results
filter = ["*"]; // return contact.displayName field
//document.getElementById("lan").innerHTML = lan;
// find contacts
navigator.contacts.find(filter, onSuccess, onError, options);
}
function onSuccess(contacts) {
for (var i = 0; i < contacts.length; i++) {
$scope.devList[i] = {text:""+contacts[i].name.formatted, emails:{email:""+contacts[i].emails[0].value,checked:false}, phno:{phone:""+contacts[i].phoneNumbers[0].value,checked:false},addres:{address: contacts[i].addresses||[],checked:false},checked: false};
$scope.emails[i] = {email:""+contacts[i].emails[0].value+""};
}
}
function onError(contactError) {
alert('onError!');
}
}
You need to call $apply if you do anything outside of angular context
function onSuccess(contacts) {
for (var i = 0; i < contacts.length; i++) {
$scope.devList[i] = {text:""+contacts[i].name.formatted, emails:{email:""+contacts[i].emails[0].value,checked:false}, phno:{phone:""+contacts[i].phoneNumbers[0].value,checked:false},addres:{address: contacts[i].addresses||[],checked:false},checked: false};
$scope.emails[i] = {email:""+contacts[i].emails[0].value+""};
$scope.$apply();
}
}

AngularJS, Add Rows

Morning,
We are trying to implement this add row Plunkr, it seems to work however our input data seems to repeat. Does anyone know of a solution to add a unique id to preview duplicated fields ?
Here is our current Plunkr and LIVE example.
$scope.addRow = function(){
var row = {};
$scope.productdata.push(row);
};
$scope.removeRow = function(index){
$scope.productdata.splice(index, 1);
};
$scope.formData you have is not an array, but just one object. All your rows are bound to that object and hence all of them reference the same data.
The reason you get a new row added is because your ng-repeat is bound to $scope.productData and you add extra record in it. You should bind your form elements to the properties in the row object that you create
a simple example is :
In your template
<div ng-repeat="product in products">
<input type="text" ng-model="product.title">
</div>
In your controller
$scope.addProduct = function(){
var product = {};
$scope.productData.add(product);
}
You'd then always only work with the productData array and bind your model to them.
Even in your backend calls, you'd use productData instead of your formData.
Hope this helps.
U can use a filter : This will return Unique rows only
app.filter('unique', function () {
return function (items, filterOn) {
if (filterOn === false) {
return items;
}
if ((filterOn || angular.isUndefined(filterOn)) && angular.isArray(items)) {
var hashCheck = {}, newItems = [];
var extractValueToCompare = function (item) {
if (angular.isObject(item) && angular.isString(filterOn)) {
return item[filterOn];
} else {
return item;
}
};
angular.forEach(items, function (item) {
var valueToCheck, isDuplicate = false;
for (var i = 0; i < newItems.length; i++) {
if (angular.equals(extractValueToCompare(newItems[i]), extractValueToCompare(item))) {
isDuplicate = true;
break;
}
}
if (!isDuplicate) {
newItems.push(item);
}
});
items = newItems;
}
return items;
};
});
I think the reason why this is happening is that the addRow() function is just pushing an empty son object into the $scope.productdata array, whereas all input fields are bound to $scope.formData[product.WarrantyTestDescription]. I think you mean to bind the input fields to the properties of the product object.

Resources