Hello I am trying to use Angularjs and I'm not very good at it. I'm trying to find something from the madeUpCards[] array. using the find() function of javascript.
I am not entirely sure, I think it's not working when I use it with Angularjs.
here is the my Code:
<body ng-app="myApp" ng-controller="myCtrl">
<h3>{{getCardById('14')}}</h3>
</body>
array here:
$scope.madeUpCards = [
{
"id": "23",
"name": "The brain",
"closed": true,
},
{
"id": "2",
"name": "Portal dead",
"closed": true,
},
{
"id": "14",
"name": "Holiday",
"closed": true,
},
{
"id": "13",
"name": "warded",
"closed": true,
},
];
javascript :
const app = /**
* myApp Module
*
* Description
*/
angular.module('myApp', []).controller('myCtrl', ['$scope', function($scope){
$scope.getCardById = function(id) {
this.id = id
let foundCard = $scope.madeUpCards.find(function(card, index){
return card.id == this.id
});
return foundCard.name;
}
}]);
in the console this appears:
angular.js:15536 TypeError: Cannot read property 'find' of undefined
at ChildScope.$scope.getCardById ((index):49)
at fn (eval at compile (angular.js:16387), <anonymous>:4:234)
at expressionInputWatch (angular.js:17398)
at Scope.$digest (angular.js:19095)
at Scope.$apply (angular.js:19463)
at bootstrapApply (angular.js:1945)
at Object.invoke (angular.js:5122)
at doBootstrap (angular.js:1943)
at bootstrap (angular.js:1963)
at angularInit (angular.js:1848)
pleas help me how to fix this, or atleast tell me what's wrong.
Change const madeUpCards to $scope.Cards in your controller, and instead of passing in Cards, just use <h3>{{ getCardById('14') }}</h3>
Then in your controller, use $scope.Cards. i.e.
In the controller:
$scope.Cards = [
{
"id": "23",
"name": "The brain",
"closed": true,
},
{
"id": "2",
"name": "Portal dead",
"closed": true,
},
{
"id": "14",
"name": "Holiday",
"closed": true,
},
{
"id": "13",
"name": "warded",
"closed": true,
},
];
...
$scope.getCardById = function(id) {
let foundCard = $scope.Cards.find(function(card, index){
return card.id == this.id
});
return foundCard.name;
}
In the HTML:
<body ng-app="myApp" ng-controller="myCtrl">
<h3>{{ getCardById('14') }}</h3>
</body>
Now you could still pass in Cards to getCardById, but it's already accessible in your controller so it would be pointless.
AngularJS will only bind elements to the DOM that are defined on the scope.
You created Cards as a local variable in the controller, but not part of the scope. So in the HTML when you pass Cards into a function, its undefined (not part of the scope).
This passes undefined into your controller, and then you attempt to call find on undefined, hence your error.
Cards is undefined, try that
<h3>{{ getCardById([
{
"id": "23",
"name": "The brain",
"closed": true,
},
{
"id": "2",
"name": "Portal dead",
"closed": true,
},
{
"id": "14",
"name": "Holiday",
"closed": true,
},
{
"id": "13",
"name": "warded",
"closed": true,
},
], '14') }}</h3>
<h3>{{ getCardById(Cards, '14') }}</h3>
According to this snippet, the variable Cards should be binded to $scope.
So, define a $scope.Cards at the initial part of the controller as below:
const app = /**
* myApp Module
*
* Description
*/
angular.module('myApp', []).controller('myCtrl', ['$scope', function($scope){
$scope.Cards = [
{
"id": "23",
"name": "The brain",
"closed": true,
},
{
"id": "2",
"name": "Portal dead",
"closed": true,
},
{
"id": "14",
"name": "Holiday",
"closed": true,
},
{
"id": "13",
"name": "warded",
"closed": true,
},
];
$scope.getCardById = function(cards, id) {
this.cards = cards
this.id = id
let foundCard = this.cards.find(function(card, index){
return card.id == this.id
});
return foundCard;
};
}]);
Happy coding.
Related
I want to assign a new Value (let say this is a flag such as isActive) from an existing object. this is an example for the object I'm using to try:
let localValue = {
"id": "019eadd3-2e71-4446-a195-69d849d88a43",
"discount": {
"code": "PFMQWERTY",
"id": "019eadd3-2e71-4446-a195-69d849d88a43",
"isActive": false
},
"discountId": "019eadd3-2e71-4446-a195-69d849d88a43",
"discountRules": [
{
"id": "1-1",
"type": "FIXED",
"value": 30000,
"package": {
"id": "1-1-A",
"name": "Package A",
"maxDiscountInApps": 3,
"discountInApps": [
{
"id": "1-1-A-A",
"code": "QWERTY",
"expirationDate": "2034-02-28T00:00:00+0000"
}
]
}
},
{
"id": "1-2",
"type": "FIXED",
"value": 100000,
"package": {
"id": "1-2-A",
"name": "Package B",
"maxDiscountInApps": 3,
"discountInApps": [
{
"id": "1-2-A-A",
"code": "KASH",
"expirationDate": "2032-02-03T00:00:00+0000"
}
]
}
},
{
"id": "1-3",
"type": "FIXED",
"value": 15000,
"package": {
"id": "1-3-A",
"name": "Package C",
"maxDiscountInApps": 3,
"discountInApps": []
}
},
{
"id": "1-4",
"type": "FIXED",
"value": 180000,
"package": {
"id": "1-4-A",
"name": "Package D",
"maxDiscountInApps": 3,
"discountInApps": []
}
},
{
"id": "1-5",
"type": "FIXED",
"value": 15000,
"package": {
"id": "1-5-A",
"name": "",
"maxDiscountInApps": 3,
"discountInApps": []
}
},
{
"id": "1-6",
"type": "FIXED",
"value": 30003,
"package": {
"id": "1-6-A",
"name": "Package E",
"maxDiscountInApps": 3,
"discountInApps": [
{
"id": "1-6-A-A",
"code": "QWERTY",
"expirationDate": "2034-02-28T00:00:00+0000"
},
{
"id": "1-6-A-B",
"code": "KASH",
"expirationDate": "2032-02-03T00:00:00+0000"
},
{
"id": "1-6-A-C",
"code": "ANT",
"expirationDate": "2021-07-30T00:00:00+0000"
}
]
}
},
{
"id": "1-7",
"type": "FIXED",
"value": 5000,
"package": {
"id": "1-7-A",
"name": "Package F",
"maxDiscountInApps": 3,
"discountInApps": []
}
}
],
"expirationDate": "28/02/2034 07:00:00",
"totalPackagesShown": 2
}
the goals I want to achieve is to check if there is the same code in discountRules.package.discountInApps.code === this.localValue.discount.code then return true, if failed then return false.
I can already find the way to set it using map() and some() like this:
this.localValue.discountRules = this.localValue.discountRules.map(
rule => ({
...rule,
isActive:
rule.package &&
rule.package.discountInApps &&
rule.package.discountInApps.length !== 0
? rule.package.discountInApps.some(
ruleItems =>
ruleItems.code === this.localValue.discount.code
)
: false
})
);
but performance wise, is it better using map() and reducer() combination for this case or better stay using map() and some()? because I read it in here Array.prototype.reduce() it seems when using reducer can make an array reduce until it finds a value that I want (is my understanding correct?) so if it's true then...
is it better using this map() and reducer() (if its possible) or stay with map() and some() combination?
(I'm still failed to implement map() and reducer(), so can someone tell me how to use this (map() and reducer()) combination?)
Notes:
if by any chance there is a better way, I'm open for it
just in case, I'm already try to read this thread but still not quite understand as how to implement it in my case:
remove-object-from-array-using-javascript
If you prefer performance, the traditional for loop would be the fastest.
For execution times, I get these
Map & Some: 27ms average
Map & Reduce: 32ms average
You can use console.time() and console.timeEnd() to check for execution times.
The array Reduce method will run a callback function on each element of the supplied array and will return the calculated value from the callback (the value will be stored in the index of the element). If you want to use reduce with map, you can do something like this
localValue.discountRules = localValue.discountRules.map((rule) => ({
...rule,
isActive:
rule.package &&
rule.package.discountInApps &&
rule.package.discountInApps.length !== 0
? rule.package.discountInApps.reduce(
(accumulatedValue, currentValue) =>
accumulatedValue && currentValue.code === localValue.discount.code,
true // this is the default initial value for the accumulatedValue
)
: false,
}));
Alternatively, you can use optional chaining (?.) Like this
localValue.discountRules = localValue.discountRules.map((rule) => ({
...rule,
isActive:
rule?.package?.discountInApps?.some(
(ruleItems) => ruleItems.code === localValue.discount.code
)
}));
(Do check out the supported browsers here).
I have an object that has a whole host of arrays and properties. There is a property called targetProperty which appears in various places of the object.
I have a function where if the user clicks yes, every instance of that property needs to be reassigned to a new value.
The problem is the function that I used for assigning a new value doesn't work in this senario:
reassingPropertyInObj(obj, status) {
if (typeof obj === 'object' && obj !== null) {
obj.targetProperty = status;
for (const key in obj) {
this.handleExpandCollapseClick(obj[key], status);
}
}
},
Does anyone have a solution for this? Also can't use JSON.parse() or anything like that because the properties need to stay reactive for later reassignment if needed by the user.
Below is an example of one object:
{
"id": 16,
"ref_study_id": "3412333",
"title": "SomePersonNameOne",
"capabilities_available": [
{
"id": 75,
"name": "Clinical Data",
},
{
"id": 538,
"name": "RK's Capability",
}
],
"capabilities_impacted": [],
"businessImpact": {
"id": 2,
"name": "Medium"
},
"sites_impacted": [],
"sites_available": []
},
{
"id": 6,
"ref_study_id": "123124",
"title": null,
"capabilities_available": [
{
"id": 37,
"name": "Clinical Site Experience,
},
{
"id": 41,
"name": "Experience",
}
],
"capabilities_impacted": [
{
"id": 37,
"name": "Information Exchange",
"is_study_level": false,
"businessImpact": {
"id": 2,
"name": "Medium"
}
},
{
"id": 39,
"name": "IT/Data Experience",
"is_study_level": false,
"businessImpact": {
"id": 2,
"name": "Medium"
}
},
{
"id": 34,
"name": "Mgmt & Storage",
"is_study_level": false,
"businessImpact": {
"id": 3,
"name": "Minor"
}
}
],
"businessImpact": {
"id": 2,
"name": "Medium"
},
"sites_impacted": [],
"sites_available": []
},
And the property in question is businessImpact. As you can see it appears by itself as a property and inside array (and sometimes those arrays of arrays of their own).
I setup a function like:
arrayOfProperties.forEach((property) => {
obj[property].forEach((o) => {
o.businessImpact = newVal;
});
});
But of course it doesn't go deep enough.
Here is the Scenario
I am getting Data from server in this form
$scope.data=[
{"name":"xyz","status":"pending"},
{"name":"abc","status":"completed"},
{"name":"pqr","status":"completed"}
]
This Data is Seprate GET call for different status
$scope.statusValues=[
{"statusName":"pending","id":"1"},
{"statusName":"completed","id":"2"},
{"statusName":"cancelled","id":"3"},
{"statusName":"custom","id":"4"}
]
In HTML:-
<div ng-repeat="t in data">{{t.name}}</div>
How to Display t.status value inside Select method with more $scope.statusValues
Use key value pair for combine them.
I have created plunker it may helpful.
Plunker
You can use ng-options to display all the status and ng-model to bind to your data status
var app = angular.module('myApp', []);
app.controller('myCtrl', function($scope) {
$scope.data = [{
"name": "ABC",
"statusId": "1",
"status": "completed"
}, {
"name": "XYZ",
"statusId": "2",
"status": "pending"
}, {
"name": "PQR",
"statusId": "3",
"status": "assigned"
}];
$scope.statusValues = [{
"statusId": "1",
"status": "completed"
}, {
"statusId": "2",
"status": "pending"
}, {
"statusId": "3",
"status": "assigned"
}, {
"statusId": "4",
"status": "cancelled"
}, {
"statusId": "5",
"status": "customstatus"
}, {
"statusId": "6",
"status": "customstatus2"
}];
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="myApp" ng-controller="myCtrl">
<div ng-repeat="t in data">
{{t.name}}
<select ng-model="t.status" ng-options="s.status as s.status for s in statusValues"></select>
</div>
</div>
EDIT
Update arrays as discussed in comments
I have a small question about knockout.
I have made a viewmodel
that looks like this (there are more subitems then Actions)
{
"PlatformSettings": [
{
"Actions": [
{
"Selected": false,
"Text": "None",
"Value": "None"
},
{
"Selected": true,
"Text": "Validation1",
"Value": "Validation1"
},
{
"Selected": true,
"Text": "Validation2",
"Value": "Validation2"
},
{
"Selected": true,
"Text": "Validation3",
"Value": "Validation3"
}
],
"Platform": {
"Id": "89",
"Description": "ONTWIKKELB"
}
},{
"Actions": [
{
"Selected": false,
"Text": "None",
"Value": "None"
},
{
"Selected": true,
"Text": "Validation1",
"Value": "Validation1"
},
{
"Selected": true,
"Text": "Validation2",
"Value": "Validation2"
},
{
"Selected": true,
"Text": "Validation3",
"Value": "Validation3"
}
],
"Platform": {
"Id": "89",
"Description": "ONTWIKKELB"
}
}
It works fine, but when i edit the checkboxes in my view and map them
self.Save = function(validate) {
var unmapped = ko.mapping.toJSON(self);
******
return false;
};
unmapped doesn't show the changes. And all the select values still show as on page load. I tried to make observable arrays, but the past 2 hours, but i can't figure it out.
Many thanks
Making the array observable will notify subscribers on add\remove. Making the "selected" property of each element observable will notify subscribers when it changes and allow 2 way binding.
So basically, make the selected property of each array element an observable too.
Consider the following JSON structure:
UPDATED:
[
{
"game0001": {
"-JfuVKIsUBH27DMJfWmL": {
"action": "STARTFIRSTHALF",
"team": "HOME"
},
"-JfuVLJGMgclLZ0Maduh": {
"action": "GOAL",
"team": "AWAY"
}
},
"$id": "events",
"$priority": null
},
{
"game0001": {
"gameRunning": false,
"startDate": "17/01/2015 17:27:42 PM"
},
"game0002": {
"gameRunning": true,
"startDate": "17/01/2015 19:45:59 PM"
},
"game0003": {
"gameRunning": false,
"scheduledDate": "17/01/2014 12:30:00 PM"
},
"$id": "games",
"$priority": null
}
]
How can I achieve filtering in AngularJS in HTML?
In a very basic way, what I'm trying to achieve is the following:
<div ng-repeat="game in games">
<div ng-repeat="event in events | filter:game">
{{event.name}} - {{game.name}}
</div>
</div>
I have 2 maps games and events which share the same keys, e.g (game0001, game0002)
While repeating the games, I would like to have a inner repeater for events and filter only the ones sharing the same key/id.
Here's a working plunkr, I made assumptions about the data you wanted to fetch:
http://plnkr.co/edit/DVwQaRZeZiagGEzY4lCy?p=preview
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.games = {
"games": {
"game0001": {
"first": "a",
"second": "b"
},
"game0002": {
"first": "c",
"second": "d"
}
}
}
$scope.gamesKeys = Object.keys($scope.games['games']);
$scope.events = {
"events": {
"game0001": {
"event": {
"key": "a"
},
"event": {
"key": "b"
},
"event": {
"key": "c"
}
},
"game0002": {
"event": {
"key": "a"
},
"event": {
"key": "b"
},
"event": {
"key": "c"
}
}
}
}
$scope.eventsKeys = Object.keys($scope.events['events']);
});
The important part is the ng-repeat here:
<body ng-controller="MainCtrl">
<div ng-repeat="gameKey in gamesKeys">
<div ng-repeat="eventKey in eventsKeys">
event: {{events['events'][eventKey].event.key}} - game: {{games['games'][gameKey].first}}
</div>
</div>
</body>