Angularjs ng-repeat passed index not defined - javascript

I am trying to toggle the button on and off in a ng-repeat, view on map works, but when it changes to remove marker, it pass me an error 'ReferenceError: passedIndex is not defined' in console log. Any way to fix that?
HTML:
<li class="displaySubCategory" ng-repeat="communityTheme in community | startFrom:currentPage*pageSize | limitTo:pageSize">
<div class="categoryImg">
<img src="img/csvIcon.png" />
<img src="img/shpIcon.png" />
</div>
<div class="categoryDesc">
<p>{{communityTheme.THEMENAME}}</p>
View on Map
Remove Marker
</div>
</li>
JS:
$scope.getMapData = function (msg, passedIndex) {
map.addLayer(cities);
$scope.Lng.length = 0;
$scope.Lat.length = 0;
$scope.dataLatLng.length = 0;
queryNameUrl = 'https://developers.onemap.sg/publicapi/themeapi/retrieveTheme?queryName=' + msg +
'&token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOjMsInVzZXJfaWQiOjMsImVtYWlsIjoicHVibGljQXBpUm9sZUBzbGEuZ292LnNnIiwiZm9yZXZlciI6ZmFsc2UsImlzcyI6Imh0dHA6XC9cL29tMi5kZmUub25lbWFwLnNnXC9hcGlcL3YyXC91c2VyXC9zZXNzaW9uIiwiaWF0IjoxNTQwOTI5OTE2LCJleHAiOjE1NDEzNjE5MTYsIm5iZiI6MTU0MDkyOTkxNiwianRpIjoiYjVkNmZkNGJhOWJiNGJiM2FkNWQzN2ZhNTAzMGIxYWEifQ.YQdfV43wrg8dX-He7-mwIL2Qhjsexq0tgNu5RotAdu4';
$http.get(queryNameUrl).then(function(response) {
$scope.apiResult = response.data.SrchResults;
$scope.apiResult.splice(0,1);
console.log($scope.apiResult)
for (var i= 0; i < $scope.apiResult.length; i++) {
if ($scope.apiResult[i].Type == "Point"){
$scope.apiResult[i].visibility = true;
console.log($scope.apiResult)
$scope.dataLatLng.push($scope.apiResult[i].LatLng)
$scope.Lat.push($scope.dataLatLng[i].split(',')[0]);
$scope.Lng.push($scope.dataLatLng[i].split(',')[1]);
L.marker([$scope.Lat[i], $scope.Lng[i]], {icon: greenIcon}).bindPopup($scope.apiResult[i].DESCRIPTION).addTo(cities);
}
// else if ($scope.apiResult[i].Type == "Polygon"){
// $scope.PolyLine.push($scope.apiResult[i].LatLng)
// console.log($scope.PolyLine)
// // for (var i = 0; i < $scope.PolyLine.length; i++) {
// // $scope.polyLineCord.push($scope.PolyLine[i])
// // // console.log($scope.polyLineCord)
// // }
// }
}
})
if($scope.community[passedIndex].visibility)
{
$scope.community[passedIndex].visibility = false;
}
else{
$scope.community[passedIndex].visibility = true;
}
}
Remove Marker:
$scope.removeMarker = function ($index) {
if($scope.community[passedIndex].visibility)
{
$scope.community[passedIndex].visibility =false;
cities.clearLayers();
}
else {
$scope.community[passedIndex].visibility = true;
}
}
Thanks for the help in advance !

You need to use track by $index
<li class="displaySubCategory" ng-repeat="communityTheme in community | startFrom:currentPage*pageSize | limitTo:pageSize track by $index">
and it should be passedIndex instead of $index in your removeMarker function
$scope.removeMarker = function (passedIndex) {

Related

Unable to add the item in array on scan in Angular 2

I am developing an application using Angular 2.. In my application I am using barcode scanner to scan in the text field and storing those items in the array.
When I scan the item get added to array, but when I scan another item the old item it replace the old value in array.
Below is the piece of code which I am using. Please help me if you see any fix for the weird issue.
import { Component,ViewChild,Input, Output,OnInit,ChangeDetectorRef } from '#angular/core';
import { FormsModule } from '#angular/forms';
import { HeaderComponent } from '../common/header.component';
//import { SaleCart } from '../model/SaleCart';
//import * as $ from "jquery";
declare var jQuery: any
#Component({
selector: 'app-test',
templateUrl: './test.component.html',
styleUrls: ['./posapp.component.css']
})
export class TestComponent implements OnInit{
title = 'Treewalker POS';
public cartItems = [];
public query;
public filteredList = [];
public products = [{"id":"3","name":"Pears Soap Original 75gm","sku":"89675432189","price":"32.00","special_price":"32.00","qty":null,"barcode":"89675432189","tax":"5","discount":"0"},{"id":"1","name":"Rin","sku":"1111111111111","price":"11.00","special_price":"11.00","qty":"10.000","barcode":"1111111111111","tax":"5","discount":"0"},{"id":"2","name":"Test 1","sku":"23456","price":"10.00","special_price":"10.00","qty":"10.000","barcode":"23456","tax":"5","discount":"0"}];
constructor() {
}
ngOnInit() {
}
add(item) {
/* check the items in the json data */
let flag = false;
var foodItem = {};
for (let product of this.products) {
if(product.barcode == item) {
flag = true;
foodItem['ctr'] = 1;
foodItem['item'] = product;
break;
}
}
let localCart = [];
if(sessionStorage.getItem("cart")){
localCart = JSON.parse(sessionStorage.getItem("cart"));
//console.log(JSON.stringify(localCart));
}
//console.log("food "+JSON.stringify(this.cart));
if(flag && localCart.length) {
let exist = 0;
for(let i=0; i < localCart.length; i++) {
if(localCart[i].item.barcode == item) {
localCart[i].ctr = parseInt(localCart[i].ctr) + 1;
//console.log("#### "+this.cart[i].ctr+" --- "+item);
exist = 1;
}
}
if(!exist){
localCart.push(foodItem);
}
sessionStorage.setItem("cart",JSON.stringify(localCart));
//this.barcode = "";
}else if(flag){
localCart.push(foodItem);
sessionStorage.setItem("cart",JSON.stringify(localCart));
}
//this.cart = JSON.parse(sessionStorage.getItem("cart"));
//this.itemsCnt = localCart.length;
//console.log("--- "+this.itemsCnt);
console.log(JSON.parse(sessionStorage.getItem('cart')));
//this.onScanProduct.emit(localCart);
}
filter(e) {
//e.preventDefault();
if (this.query !== ""){
this.filteredList = this.products.filter(function(el){
if(el.barcode.toLowerCase() == this.query.toLowerCase()) {
return el.barcode.toLowerCase() == this.query.toLowerCase();
}else{
return el.barcode.toLowerCase().indexOf(this.query.toLowerCase()) > -1;
}
}.bind(this));
/* scanned item will be added to the cart */
console.log(this.filteredList.length);
if(this.filteredList.length > 0 && e.which == 13){
//console.log(JSON.stringify(this.filteredList));
for (let product of this.filteredList) {
//console.log(filter.barcode+"=="+this.query);
if(product.barcode == this.query) {
this.add(product.barcode);
jQuery('#barcode').val("");jQuery('#barcode').focus();
this.filteredList = [];
}
}
}
}else{
this.filteredList = [];
}
}
}
Below is the html template
<div class="content-wrapper">
<section class="content">
<form>
<div class="row">
<!-- sales item add window -->
<!-- end -->
<div class="col-sm-4">
<div class="box box-primary">
<div class="box-body">
<div class="form-group">
<div class="row">
<div class="col-md-9">
<!--<input type="text" class="form-control" id="barcode" name="barcode" [(ngModel)]="barcode" (ngModelChange)="add($event)"
placeholder="Enter item code or scan the barcode" autocomplete="off" />-->
<input id="barcode" type="text" class="form-control validate filter-input" name="query" [(ngModel)]="query" (keyup)="filter($event)" placeholder="Enter item code or scan the barcode" autocomplete="off" [ngModelOptions]="{standalone: true}">
</div>
<div class="suggestions" *ngIf="filteredList.length > 0">
<ul>
<li *ngFor="let item of filteredList" >
<a (click)="select(item)" href="javascript:;">{{item.barcode}} {{item.name}}</a>
</li>
</ul>
</div>
<div class="col-md-3">
<button type="button" class="btn btn-primary" (click)="createnewproduct(newproduct)">New Product</button>
</div>
</div>
</div>
</div> <!-- end of box body -->
</div>
</div>
</div><!-- end of row -->
</form>
</section>
</div>
Below is the input field which is being used to scan the barcode
<input id="barcode" type="text" class="form-control validate filter-input" [(ngModel)]="query" (keyup)="filter()" placeholder="Enter item code or scan the barcode" autocomplete="off">
I am assuming you are using only the function add. I tried to implement in a javascript like in the following code but I am pretty sure you are referencing that object somewhere else and you are changing it. That's my conclusion but I might be wrong.
var factoryP = (function(){
function P() {
this.cart = [];
this.products = [{'barcode': 1, 'name': 'a'}, {'barcode': 1, 'name': 'b'}]
}
function add(item) {
/* check the items in the json data */
//console.log("cart length "+JSON.stringify(this.cart));
let flag = false;
var foodItem = {};
for (let product of this.products) {
if(product.barcode == item) {
//console.log("check "+item);
flag = true;
foodItem['ctr'] = 1;
foodItem['item'] = product;
break;
}
}
if(flag && this.cart.length) {
let exist = 0;
for(let i=0; i < this.cart.length; i++) {
if(this.cart[i].item.barcode == item) {
//console.log("Same product");
this.cart[i].ctr = parseInt(this.cart[i].ctr) + 1;
exist = 1;
}
}
if(!exist){
console.log(foodItem);
this.cart.push(foodItem);
}
}else if(flag){
console.log("step 4 "+item);
this.cart.push(foodItem);
}
}
P.prototype.add = add;
return new P();
});
instanceP = factoryP();
instanceP.add(1);
instanceP.add(1);
instanceP.add(1);
instanceP.add(2);
console.log(instanceP.cart[0].ctr)
//output 3
instanceP.cart[1].ctr
//output 1
Check your code here. Every time you are initializing the foodItem array with empty array. So whenever code will call add method, it will first empty your foodItem array.
Please check my comment in your code below:
add(item) {
let flag = false;
//Akshay: You need to make your changes here. Initialize your foodItem array out of this scope
var foodItem = {};
for (let product of this.products) {
if(product.barcode == item) {
//console.log("check "+item);
flag = true;
foodItem['ctr'] = 1;
foodItem['item'] = product;
break;
}
}

How can I improve adding/removing items to an array code

I have a list of items, I want to remove or add an item from myStockif it is selected or deselected. The problem I am having is once an item is selected the browser crushes. Is the a way I can do this better?
HTML:
<ion-list>
<div *ngFor="let item of stockList | speciesSearchPipe:listFilter.value">
<ion-item>
<ion-label>
{{ item.name_eng }}
<img src="./assets/images/species_icons/{{item.image_file}}" width="60" style="float: right;"/>
</ion-label>
<ion-checkbox class="item-avatar item-checkbox-right" color="dark" checked="false" (click)="selectSpecie(item)"></ion-checkbox>
</ion-item>
</div>
</ion-list>
TS:
let myStock = this.apiService.currentUser.data.coop.jdata;
if (myStock) {
for (let x = 0; myStock.stocklist.length > x; x++) {
myStock.stocklist["fish_species_id"] === item.fish_species_id ? myStock.stocklist.splice(x,1) : myStock.stocklist.push(item);
};
} else {
myStock = {};
myStock["stocklist"] = [];
myStock.stocklist.push(item);
};
console.log(myStock); // First log is as expected, then the app freezes
Try replacing your for-loop with this:
let index = myStock.stocklist.indexOf(item);
if(index >= 0) {
myStock.stocklist.splice(index, 1);
} else {
myStock.stocklist.push(item);
}
Full code:
let myStock = this.apiService.currentUser.data.coop.jdata;
if (myStock) {
let index = myStock.stocklist.indexOf(item);
if (index >= 0) {
myStock.stocklist.splice(index, 1);
} else {
myStock.stocklist.push(item);
}
} else {
myStock = {};
myStock["stocklist"] = [];
myStock.stocklist.push(item);
};
console.log(myStock);
if (!myStock) {
myStock = {
stockList: [item]
};
} else {
const index = myStock.stockList.findIndex(({item.fish_species_id}) => item.fish_species_id === item.fish_species_id);
if(index !== -1) {
myStock.stockList[index] = item;
} else {
myStock.stockList.push(item);
}
}
console.log(myStock);

Set the value of a nested radio button

I have many list of radio button in a ng-repeat.
I've succeded for get the selected item.
Now I try to set the default value of the radio.
Can some one help me please. Here my code for the button.
Thank's
VariableRadioArr2 = [{"id":"21","libelle":"P15m","type":"radio","valeur_1":"Oui","valeur_2":"Non","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""},{"id":"25","libelle":"Surface (m²)","type":"input","valeur_1":"","valeur_2":"","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""},{"id":"36","libelle":"p16","type":"radio","valeur_1":"Oui","valeur_2":"Non","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""}]
$scope.itemGroups = VariableRadioArr2;
console.log(VariableRadioArr2);
//$scope.selected = 1;
$scope.VariableRadioToggle2 = true;
$scope.clickedVariableRadio2 = function(test)
{
$scope.clickedVariableRadio2_select = JSON.parse(JSON.stringify($scope.itemGroups));
}
if(VariableRadioArr2.length == 0)
{
$scope.clickedVariableRadio2_select = [];
$scope.VariableRadioToggle2 = false;
}
<ion-list id="page-list7" ng-show="VariableRadioToggle2">
<div ng-repeat="itemGrp in itemGroups">
<ion-item class="item-divider" id="page-list-item-divider32">{{itemGrp.name}}</ion-item>
<ion-toggle name="{{itemGrp.name}}" ng-click="clickedVariableRadio2(portion.selected)" ng-repeat="(key,portion) in itemGrp.Portions" ng-model="itemGrp.selected_item" ng-true-value="'{{key}}'" ng-false-value="">{{portion.name}}</ion-toggle>
</div>
</ion-list>
Here I'm doing a loop from 1-10 to copy the values into a new object and delete the old ones.
var myApp = angular.module('myApp',[]);
function MyCtrl($scope) {
var Variable = [{"id":"21","libelle":"P15m","type":"radio","valeur_1":"Oui","valeur_2":"Non","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""},{"id":"25","libelle":"Surface (m²)","type":"input","valeur_1":"","valeur_2":"","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""},{"id":"36","libelle":"p16","type":"radio","valeur_1":"Oui","valeur_2":"Non","valeur_3":"","valeur_4":"","valeur_5":"","valeur_6":"","valeur_7":"","valeur_8":"","valeur_9":"","valeur_10":""}];
// Create sub object for all values
// and delete the old values
for (i = 0; i < Variable.length; i++) {
Variable[i].values = {};
Variable[i].selected = '';
for (v = 1; v < 11; v++) {
if(Variable[i]['valeur_'+v] != undefined){
Variable[i].values['valeur_'+v] = Variable[i]['valeur_'+v];
delete Variable[i]['valeur_'+v];
}
}
}
$scope.itemGroups = Variable;
// Set defaults
// By index
$scope.itemGroups[1].selected = 'valeur_4';
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.1/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyCtrl">
<div ng-repeat="itemGrp in itemGroups">
<div>{{itemGrp.libelle}}</div>
<label ng-repeat="(key, value) in itemGrp.values">
<input type="radio" name="{{itemGrp.id}}" ng-model="itemGrp.selected" ng-value="key">{{value}}
</label>
</div>
</div>

how to make a correct search when pagination

I can not understand. How to make a correct search when pagination?
English for bad writing.
I did so:
var app = angular.module('appTelDirectory', []);
app.controller('directoryList', function($scope) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.users = [{}]
$scope.numberOfPages = function() {
return Math.ceil($scope.users.length / $scope.pageSize);
}
for (var i = 0; i < 45; i++) {
$scope.users.push({
'name': 'user' + i
});
}
});
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="appTelDirectory" ng-controller="directoryList">
<input placeholder="Поиск..." ng-model="searchAll" class="form-control">
<ul>
<li ng-repeat="item in users | filter:searchAll | startFrom:currentPage*pageSize | limitTo:pageSize">{{item.name}}</li>
</ul>
<table>
<tr ng-repeat="item in users | startFrom:currentPage*pageSize | limitTo:pageSize">
</table>
<button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">Previous</button>
{{currentPage+1}}/{{numberOfPages()}}
<button ng-disabled="currentPage >= users.length/pageSize - 1" ng-click="currentPage=currentPage+1">
Next
</button>
</div>
How do I change the number of items, depending on the user list. NumberOfPages unchanged...
You can use a separate list for it like this. Basically, I'm using another list filteredUsers. Now instead of using filter in the view i.e. filter:searchAll, I'm doing the same thing using the underlying $filter service in the $watch which will be invoked as I type in the field.
Now, we always have the filtered users in the filteredUsers scope variable so your further calculation now can be based on the $scope.filteredUsers not on $scope.users.
var app = angular.module('appTelDirectory', []);
app.controller('directoryList', function($scope, $filter) {
$scope.currentPage = 0;
$scope.pageSize = 10;
$scope.users = [{}];
// Using a separate list of filtered users
$scope.filteredUsers = [{}];
$scope.numberOfPages = function() {
return Math.ceil($scope.filteredUsers.length / $scope.pageSize);
}
for (var i = 0; i < 45; i++) {
$scope.users.push({
'name': 'user' + i
});
}
$scope.filteredUsers = angular.copy($scope.users);
$scope.$watch('searchAll', function(newValue) {
// Manually filtering here instead doing in the view
$scope.filteredUsers = $filter('filter')($scope.users, {$: newValue});
});
});
app.filter('startFrom', function() {
return function(input, start) {
start = +start; //parse to int
return input.slice(start);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="appTelDirectory" ng-controller="directoryList">
<input placeholder="Поиск..." ng-model="searchAll" class="form-control">
<ul>
<li ng-repeat="item in filteredUsers | startFrom:currentPage*pageSize | limitTo:pageSize">{{item.name}}</li>
</ul>
<table>
<tr ng-repeat="item in users | startFrom:currentPage*pageSize | limitTo:pageSize">
</table>
<button ng-disabled="currentPage == 0" ng-click="currentPage=currentPage-1">Previous</button>
{{currentPage+1}}/{{numberOfPages()}}
<button ng-disabled="currentPage >= filteredUsers.length/pageSize - 1" ng-click="currentPage=currentPage+1">
Next
</button>
</div>

prevent adding duplicate items to the basket

I have created a basket in my PHP form where users can insert their selected movies to it.
Question:
How can I prevent adding duplicate movies to this basket (selected movie list)?
Here is my code: (Sorry, I didn't paste all the code since it was too long)
<div id="basket">
<div id="basket_left">
<h4>Selected Movies</h4>
<img id="basket_img" src="http://brettrutecky.com/wp-content/uploads/2014/08/11.png" />
</div>
<div id="basket_right">
<div id="basket_content">
<span style="font-style:italic">Your list is empty</span>
</div>
</div>
</div>
<script type="text/javascript">
var master_basket = new Array();
$(document).ready(function () {$("input[id='selectType']").change(function(){
// AUTO_COMPLETION PART
$('#btnMove').on('click', function(d) {
console.log(master_basket);
d.preventDefault();
var selected = $("#q").val();
if (selected.length == 0) {
alert("Nothing to move.");
d.preventDefault();
} else {
var obj = {
"movie_name":selected,
"movie_info": ""
};
addToBasket(obj);
}
$("#q").val("");
});
});
function addToBasket(item) {
master_basket.push(item);
showBasketObjects();
}
function showBasketObjects() {
$("#basket_content").empty();
$.each(master_basket, function(k, v) {
$("#basket_content").append("<div class='item_list'>" + v.movie_name + "<a class='remove_link' href='" + k + "'><img width='20' src='http://i61.tinypic.com/4n9tt.png'></a></div>");
});
I personally wouldn't suggest using javascript to prevent this duplication thing since anyone could modify it and manually cause this problem, you should prevent the duplication both in php and javascript.
Anyway to accomplish what you want in the script I think it's enough to modify part of your code to this:
var master_basket = new Array();
selectedMovies = {};
///////
} else {
var obj = {
"movie_name":selected,
"movie_info": ""
};
if(!selectedMovies.hasOwnProperty(selected)){
addToBasket(obj);
selectedMovies[selected] = obj;
}
}
Try modifying your function to
function addToBasket(item) {
var ifExists = false;
for (i = 0; i < master_basket.length; ++i) {
if(master_basket[i] == item)
ifExists = true;
}
if(!ifExists)
master_basket.push(item);
}
}

Categories