ngChange is not picking up changes from the model - angularjs

I am trying to access the obj from the select in my controller but the only thing that I end up getting is null and undefined.
<select
ng-change="watchActions(part)"
ng-options="part.serial as part.description for part in rawBaList.items"
ng-model="currentChose"
></select>
$scope.currentChose = null;
$scope.watchActions = function (obj) {
console.log($scope.currentChose);
console.log(obj);
};
$scope.$watch('currentChose', function (newValue, oldValue) {
if(newValue){
console.log("here the new value goes");
}
});
Here is the ex of data:
{
count: 2,
items: [
{serial: 2, description: 'here is some description'},
{serial: 24, description: 'some other description'}
]
}

it was a scope issue, $parent.currentChose fixed it

Related

Vue.js filtering on array

I am trying to filter an array using a computed property in vue.js. I would like to search on on multiple fields, name, state, tags etc.
My data:
events: [
{
id: 1,
name: 'Name of event',
url: '#',
datetime: '2017-05-10T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'ordinary',
'advanced'
]
},
{
id: 2,
name: 'Another event',
url: '#',
datetime: '2017-05-12T00:00:00Z',
description: 'The full text of the event',
state: 'VIC',
tags: [
'beginner'
]
},
{
id: 3,
name: 'Great event',
url: '#',
datetime: '2017-05-18T00:00:00Z',
description: 'The full text of the event',
state: 'NSW',
tags: [
'beginner'
]
}
]
},
The following function works as expected, however I cant work out how to have it search the items in 'tags' (commented out).
searchevents: function(){
let result = this.events
if (this.filterValue){
result = result.filter(event =>
event.name.toLowerCase().includes(this.filterValue.toLowerCase()) ||
event.state.toLowerCase().includes(this.filterValue.toLowerCase())
// event.tags.toLowerCase().values().includes(this.filterValue.toLowerCase())
)
}
return result
}
The following returns a blank array, this method works ok when i have done it in angular but not in vue.
searchevents2: function(){
var searchRegex = new RegExp(this.filterValue,'i')
this.events.filter(function(event){
return !self.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state)
})
}
Ideally I would either like to be able to list array items to filter by or just filter by the entire array.
Appreciate any help, first post here so be gentle. I have a lot more experience with Python than Javascript so i may also use incorrect terminology at times.
You weren't too far off.
For your searchEvents filter, you just needed to add the tag filter. Here's how you might do that.
searchevents: function(){
let result = this.events
if (!this.filterValue)
return result
const filterValue = this.filterValue.toLowerCase()
const filter = event =>
event.name.toLowerCase().includes(filterValue) ||
event.state.toLowerCase().includes(filterValue) ||
event.tags.some(tag => tag.toLowerCase().includes(filterValue))
return result.filter(filter)
}
Array.some() is a standard array method that returns true if any element of the array passes your test.
searchevents2: function(){
const searchRegex = new RegExp(this.filterValue,'i')
return this.events.filter(event =>
!this.filterValue || searchRegex.test(event.name) || searchRegex.test(event.state))
}
With searchEvents2 you really only left an errant self in there. Either you needed to set self before you executed the filter, or, as I have done here, turned it into an arrow function.
Example.
const app = new Vue ({
el: '#app',
data: {
search: '',
userList: [
{
id: 1,
name: "Prem"
},
{
id: 1,
name: "Chandu"
},
{
id: 1,
name: "Shravya"
}
]
},
computed: {
filteredAndSorted(){
// function to compare names
function compare(a, b) {
if (a.name < b.name) return -1;
if (a.name > b.name) return 1;
return 0;
}
return this.userList.filter(user => {
return user.name.toLowerCase().includes(this.search.toLowerCase())
}).sort(compare)
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<div id="app">
<div class="search-wrapper">
<input type="text" v-model="search" placeholder="Search title.."/>
<label>Search Users:</label>
</div>
<ul>
<li v-for="user in filteredAndSorted">{{user.name}}</li>
</ul>
</div>

How to get and compare values in table from another table in angularjs?

I am new at angularjs. So, it might be fool question.Anyway, please let me explain my problem. I have a table which is listed by ng-repeat and I'd like to change a column datas with another datas in another table column.
<tr data-ng-repeat=" list in listTypes">
<td>{{list.Comments}}</td>
<td>{{list.Modul}}</td>
<td>{{list.UserId}}</td>
<td data-ng-repeat="user in userNames">{{user.UserName}}</td>
I want to get UserName instead of UserId, but the problem that UserName is recorded in another table. Here is my angular for getting listTypes :
$scope.GetList = function () {
var onSuccess = function (response, status) {
//1
$scope.listTypes = response.Data;
var str = response.Data;
$scope.listTypes = eval('(' + str + ')');
for (var key in $scope.listTypes) {
$scope.listTypes[key].selected = "";
}
$scope.GetUserNames();
};
var data = null;
var request = $rest.GetList(data);
NGTools.CallNgServiceWithRequest(request, onSuccess, "GetList");
};
And trying to get usernames with this code:
$scope.userdatas= [];
$scope.userNames = [];
$scope.GetUserNames = function () {
var onSuccess = function (response, status) {
//1
$scope.userNames = response.Data;
};
$scope.userdatas= $scope.listTypes.UserId;
var data = { userdatas: JSON.stringify( $scope.userdatas) };
var request = $rest.GetUserNames(data);
NGTools.CallNgServiceWithRequest(request, onSuccess, "GetUserNames");
};
but it doesn't work. I couldn't figure out what's wrong with this code block. Please let me know if any tip is available. Thank you!
Assuming that you have to collections in your scope - one of which holds the id of the user, and the other holding the name, like so:
$scope.users = [
{ id: 1, name: 'John Doe' },
{ id: 2, name: 'Jane Doe' },
{ id: 3, name: 'Janice Doe' } ];
$scope.userInfo = [
{ userId: 1, gender: 'male' },
{ userId: 2, gender: 'female' },
{ userId: 3, gender: 'female' }];
Then what you could do is ng-repeat over the one with the userInfo and in your binding expression - use the id to get the name from the other collection:
<li ng-repeat="item in userInfo">
{{ item.gender }} {{ getNameFor(item.userId) }}</li>
Where the getNameFor is defined as:
$scope.getNameFor = function(id) {
var user = $scope.users.filter(function(item) { return item.id === id })[0];
console.log(user);
return user.name;
Which I checked in a fiddle here: http://jsfiddle.net/01kmoxw9/

Angular with Coffeescript: why my method are executed?

I'm an angular beginner, and coming from Ruby I choose to use Coffescript instead of JS. I'm using ng-classify to define my controller, services and Factory with Coffeescript classes, but I cannot understand what is wrong.
I have my code in this [github repo], but I try to explain here my issue.
I have this controller
class Setting extends Controller
constructor: (#DataService,$log) ->
#examType = #DataService.getObject('setting_examtype') || { checked: false }
#settingList = #DataService.getObject('setting_list') || [
{ text: 'Dai precedenza a domande sbagliate', checked: false },
{ text: 'Dai precedenza a domande mai fatte', checked: false },
{ text: 'Mostra subito la soluzione', checked: false }
]
#questionPossibility = [10,20,30,40,50]
#questionNumber = #DataService.get('question_number') || 30
return
examTypeChecked: () =>
#DataService.setObject('setting_examtype',#examType)
console.log 'examTypeChecked'
return
settingListChecked: () =>
console.log 'settingListChecked'
#DataService.setObject('setting_list',#settingList)
return
questionNumberChecked: () =>
console.log 'questionNumberChecked'
#DataService.set('question_number',#questionNumber)
return
The compiled version is:
(function() {
var Setting,
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
Setting = (function() {
function Setting(DataService, $log) {
this.DataService = DataService;
this.questionNumberChecked = __bind(this.questionNumberChecked, this);
this.settingListChecked = __bind(this.settingListChecked, this);
this.examTypeChecked = __bind(this.examTypeChecked, this);
this.examType = this.DataService.getObject('setting_examtype') || {
checked: false
};
this.settingList = this.DataService.getObject('setting_list') || [
{
text: 'Dai precedenza a domande sbagliate',
checked: false
}, {
text: 'Dai precedenza a domande mai fatte',
checked: false
}, {
text: 'Mostra subito la soluzione',
checked: false
}
];
this.questionPossibility = [10, 20, 30, 40, 50];
this.questionNumber = this.DataService.get('question_number') || 30;
return;
}
Setting.prototype.examTypeChecked = function() {
this.DataService.setObject('setting_examtype', this.examType);
console.log('examTypeChecked');
};
Setting.prototype.settingListChecked = function() {
console.log('settingListChecked');
this.DataService.setObject('setting_list', this.settingList);
};
Setting.prototype.questionNumberChecked = function() {
console.log('questionNumberChecked');
this.DataService.set('question_number', this.questionNumber);
};
return Setting;
})();
angular.module('app').controller('settingController', ['DataService', '$log', Setting]);
}).call(this);
As you can see I insert some log statement, and from the console I understand that all my methods are executed. Why? Why examTypeChecked is called?
I call it only if someone use a toggle..
<ion-toggle ng-model="setting.examType" ng-checked="setting.examTypeChecked()" toggle-class="toggle-calm" ng-true-value="oltre" ng-false-value="entro">Tipo di esame</ion-toggle>
You got it wrong way, your code is fine, use of code is not what you expected
<ion-toggle ng-model="setting.examType" ng-checked="setting.examTypeChecked()" toggle-class="toggle-calm" ng-true-value="oltre" ng-false-value="entro">Tipo di esame</ion-toggle>
setting.examTypeChecked() will be called every time $digest() process is triggered, and it's triggered with each change of model, by $scope.apply(), $scope.digest(), $timeout() and few more

AngularJS matching data between json arrays and setting a selected option

$scope.opts =
{
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"}
]
}
The above is my options list array and now I set my default option.
$scope.user.unit = $scope.opts.unit[0];
The above creates the following in my html
<select class="unit ng-pristine ng-valid" data-ng-options="a.name for a in opts.unit" data-ng-model="user.unit">
<option value="0" selected="selected">px</option>
<option value="1">%</option>
</select>
When I use the below I am pulling the data that was stored in a db from the options selected in the above example.
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
console.log($scope.user.unit);
});
This console.logs me the following Object { id=1, val="px", name="px"}
I may be wrong but the <select> box is binded to $scope.opts
How would I be able to link the retrieved data from $scope.user.unit to $scope.opts.unit so that when the data is retrieved it will then mark the correct option as :selected?
I'm not 100% sure but you can try this (or create JSFiddle):
JS:
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
$scope.selected = {};
angular.forEach($scope.opts.unit, function (value)
{
if (value.val == $scope.user.unit.val) {
$scope.selected = value
}
});
console.log($scope.user.unit);
});
and in View:
<select class="unit ng-pristine ng-valid" data-ng-options="a.name for a in opts.unit" data-ng-model="user.unit">
<option value="{{selected.val}}">{{selected.name}}</option>
</select>
Your ng-model for the select element is an object, and not a primitive type, which is fine, but then you reassign $scope.user to a brand new object (returned from $http.get), so user.unit is a new object too, so it's not identical to any of your ng-options. I can think of two ways which should fix the problem:
bind the select to the 'id' property of the unit object:
<select ng-options="a.id as a.name for a in opts.unit" ng-model="user.unit.id">
or leave the select bound to user.unit, but use the track by feature of ng-options:
<select ng-options="a.name for a in opts.unit track by a.id" ng-model="user.unit">
One of the things in Angular is that you rarely need to do is explicitly create <option> elements manually as the framework will generate this for you. Therefore, the following will work: (Working jsfiddle at http://jsfiddle.net/LMHLq/12/)
HTML:
<select data-ng-model='user.unit' data-ng-options="o.id as o.name for o in opts.unit"/>
JavaScript:
$scope.opts ={
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"},
{ id: 3, val: "pt", name: "pt"}
]
}
$http.get('/assets/inc/file.php?id='+thisPage).success(function(response) {
var userData = response.userData;
var locationData = response.locationData;
$scope.user = userData;
$scope.locations = locationData;
console.log($scope.user.unit);
});
$scope.opts ={
unit: [
{ id: 1, val: "px", name: "px"},
{ id: 2, val: "%", name: "%"},
{ id: 3, val: "pt", name: "pt"}
]
}
I noticed that the $scope.opts builds my select element and populates it but when the data is retrieved via db it needs to go into $scope.user.unit but this is binded to $scope.opts so what I have done is sought out the ID for the item that was retrieved and then added -1 to it so it will select from the array of $scope.opts.unit
var testUnit = $scope.user.unit.id-1; //gets the ID of the unit thats been retrieved
$scope.user.unit = $scope.opts.unit[testUnit]; //sets the selected option in the dom

Angular JS - angular.forEach - How to get key of the object?

I have JSON object like below
{
"txt_inc_Application": {
"EWS": true,
"EWindow": true
},
"txt_inc_IncidentType": {
"Brand Damage": true,
"Internal failure": true
}
}
And I am using angular.forEach to get the values
$scope.filterFormula=function() {
angular.forEach($scope.filters, function(filterObj , filterIndex) {
angular.forEach(filterObj, function(value , key) {
console.log(value+"--"+key)
})
})
}
How can i get "txt_inc_Application" and "txt_inc_IncidentType" in the loop?
Also when call the angular function in html like below why it is getting executed twice?
{{filterFormula()}}
The first parameter to the iterator in forEach is the value and second is the key of the object.
angular.forEach(objectToIterate, function(value, key) {
/* do something for all key: value pairs */
});
In your example, the outer forEach is actually:
angular.forEach($scope.filters, function(filterObj , filterKey)
var obj = {name: 'Krishna', gender: 'male'};
angular.forEach(obj, function(value, key) {
console.log(key + ': ' + value);
});
yields the attributes of obj with their respective values:
name: Krishna
gender: male

Resources