Search array without ng-repeat in Angular - angularjs

I'm fairly new in Angular and have an object I'm creating during the user flow. The user is basically setting some preferences, including choosing an avatar from a set of available images. I need to be able to show that avatar as associated with that individual. I need to do it by ID since these avatars will be stored in a DB for launch.
I want to set the background image of a dom element to this image.
Here's a plunkr showing what I'm trying to do. ng-repeat doesn't seem right for an inline style to me. Other options? Sample code:
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.avatars = [
{
'id': 1,
'image': '../images/placeholder/avatar-settings-dog.png'
},
{
'id': 2,
'image': '../images/placeholder/avatar-settings-ladybug.png'
},
{
'id': 3,
'image': '../images/placeholder/avatar-settings-cat.png'
},
{
'id': 4,
'image': '../images/placeholder/avatar-settings-horse.png'
}
];
$scope.users = [
{
'id': 0,
'name': 'Joe',
'avatarID': 2
},
{
'id': 1,
'name': 'Mary',
'avatarID': 4
}
]
});
and the view:
<div ng-controller="MainCtrl">
<p ng-repeat="user in users" style="background:url(AVATAR PATH);">Hello {{user.name}}!</p>
</div>

Use ng-style to programmatically set the style.
<p ng-repeat="user in users"
ng-style="getAvatarBackground(user)">Hello {{user.name}}</p>
And then your controller:
$scope.getAvatarBackground = function(user) {
var avatar = // find the correct object in $scope.avatars based on user.avatarID
return {
background: "url('" + avatar.image + "');"
}
}
And an example to find the avatar object:
function findAvatarById(avatarId) {
for(var i = 0; i < $scope.avatars.length; i++) {
if($scope.avatars[i].id === avatarId) {
return $scope.avatars[i]
}
}
}
And then
var avatar = findAvatarById(avatarId);

use this code:
see plunker
Html code:
<body ng-controller="MainCtrl">
<p ng-repeat="user in users" style="background:url({{returnimageurl(user)}});">Hello {{user.name}}!</p>
</body>
and Js code:
$scope.returnimageurl=function(user){
for( key in $scope.avatars){
if(user.avatarID==$scope.avatars[key].id){
return $scope.avatars[key].image;
}
}
}

Related

angularjs $compile html template in forEach not update variables

I want to dynamically generate html. I have generateHtml function contains loop for items, currently it is not displaying proper variables added in template. It is always display the last items data on all the iteration on compiled html.
Following is the controller & template code
This is my controller code
angular.module('app').controller('PageController', ['$scope', '$sce', '$compile','$templateRequest',
function ($scope, $sce, $compile,$templateRequest) {
$scope.itemsHtml = '';
// Array contains dynamic data
vm.items = [{
id: 1,
name: 'abc',
}, {
id: 2,
name: 'pqr',
}, {
id: 3,
name: 'stu',
}, {
id: 4,
name: 'xyz',
}];
vm.currentItem = [];
let templateUrl = $sce.getTrustedResourceUrl('/views/item.html');
$templateRequest(templateUrl).then(function(template) {
vm.itemTemplate = template;
}, function() {
});
vm.generateHtml = function() {
items.forEach(function (item, key) {
vm.currentItem = item;
let compiledTemplate = $compile(vm.itemTemplate)($scope).html();
/* Append compiled dynamic html */
$scope.itemsHtml += compiledTemplate;
});
}
function init() {
vm.generateHtml();
}
init();
}
]);
This is template view
<script type="text/ng-template" id="item.html">
<div className="item-wrapper">
<div className="item-inner">
{{ pageCtrl.currentItem.name }}
</div>
<div className="action-inner">
<div className="btn-action"
role="button"
ng-click="pageCtrl.edit(
pageCtrl.currentItem.id
)">
<i className="fa fa-plus"></i>
</div>
</div>
</div>
</script>
I got the solution for this issue.
Actually when we use compile after that we have to interpolate the compiled template
compiledTemplate = $interpolate(compiledTemplate)($scope);
let compiledTemplate = $compile(vm.itemTemplate)($scope).html();
/* Here interpolated compiled template */
compiledTemplate = $interpolate(compiledTemplate)($scope);
/* Append compiled dynamic html */
$scope.itemsHtml += compiledTemplate;

Angularjs: evaluate expression inside HTML tag

Note this question is a bit different from the similar titled here or here. What I want to do is to "evaluate inside the HTML tag" not inside a directive (or in the controller). This description can be wrong or hard to understand but I cannot find a better way; so I made bellow self-contained code to illustrate. You may copy and past and save as "xyz.html" and see what I mean.
<!DOCTYPE html>
<html ng-app="myApp">
<head>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.6/angular.min.js"></script>
<script>
'use strict';
let app = angular.module('myApp', []);
app.controller('myCtrl', ['$scope', function ($scope) {
let d = DATA_TYPE;
let e = EDIT_TYPE;
$scope.tbContents = {
fields: [
{name: 'name', dataType: d.text, editType: e.text, refs:[]},
{name: 'catalog', dataType: d.text, editType: e.dropdown, refs: ['catalog1', 'catalog2', 'catalog3']},
{name: 'status', dataType: d.int, editType: e.dropdown, refs: [1, 2, 3, 4]}],
rows: [
{name: 'name1', catalog: 'catalog1', status: 1},
{name: 'name2', catalog: 'catalog1', status: 1},
{name: 'name3', catalog: 'catalog2', status: 2}
]
};
$scope.refNameKey = '';
$scope.setRefNameKey = function(key) {
$scope.refNameKey = key;
};
$scope.getRefByNameKey = function(key) {
let res = [];
for(let i = 0; i < $scope.tbContents.fields.length; i++) {
if($scope.tbContents.fields[i].name == key) {
return $scope.tbContents.fields[i].refs;
}
}
};
}]);
app.filter('filterDropdown', function () {
return function (fields) {
let output = [];
for (let i = 0; i < fields.length; i++) {
if (fields[i].editType == EDIT_TYPE.dropdown) {
output.push(fields[i]);
}
}
return output;
};
});
const DATA_TYPE = {
int: 1,
text: 2,
//...
};
const EDIT_TYPE = {
dropdown: 1,
test: 2,
//...
};
</script>
</head>
<body>
<div ng-controller="myCtrl">
<div>
<!--<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>-->
<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>
</div>
<hr />
<div ng-show = "refNameKey">
<p ng-repeat = "ref in getRefByNameKey(refNameKey)">{{ref}}</p>
</div>
</div>
</body>
</html>
What I want is the line I commented in the HTML code, refNameKey=field.name instead of setRefNameKey(field.name). I don't know why refNameKey=field.name does not work, but I don't like creating the setRefNameKey function for this simple task.
ng-repeat creates child scope for each iteration. So your refNameKey variable is created in each child scope and its not referring to the refNameKey in parent scope. You can fix this by modifying it like this:
<p ng-repeat="field in tbContents.fields | filterDropdown">{{field.name}}</p>
Plunker : http://plnkr.co/edit/mcDvGqd6SFCfmqyfUNRc?p=preview

ng-repeat with checkboxes and capture value

Still new to angular and js. I have a list:
<ul ng-repeat="rate in resources">
<li> <input type="checkbox" ng-model="isSelected" ng-change="appendList(rate)"> </li>
</ul>
When a user clicks on them, i'd like the value to be pushed to a list:
$scope.rateValues = {
'rates': {
'fastrates': {
'value': '',
}
}
};
But I'd like to append a key, value pair to the fastrates like this:
$scope.rateValues = {
'rates': {
'fastrates': {
'value': '100',
'value': '200',
'value': '300',
'value': '400',
}
}
};
I guess i'm stuck on my ng-change function in my controller to handle this. I know this is far from complete but at least the value changes. I need to make it check if it has been added and if so then remove it from the key, value from the object. If it's unchecked and they check it. It needs to create a new 'value': rate pair in the fastrates obj.
$scope.appendList = function(rate){
$scope.rateValues.rates.fastrates.value = rate
}
Here's a plnkr I started http://plnkr.co/edit/MhqEp7skAdejdBRpXx2n?p=info. Any scripting advice on how to accomplish this?
You can't use same key multiple times. You can use array of object.
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.resources = {value:['100','200','300', '400']}
$scope.rateValues = {
'rates': {
'fastrates': []
}
};
$scope.appendList = function(rate){
$scope.rateValues.rates.fastrates.push({ value: rate });
}
});
Don't forget to remove value when you uncheck the checkbox.
http://plnkr.co/edit/MhqEp7skAdejdBRpXx2n?p=preview removing value from array when you uncheck checkbox
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.resources = {
value: ['100', '200', '300', '400']
}
$scope.rateValues = {
'rates': {
'fastrates': {
'value': [],
}
}
};
$scope.appendList = function(rate) {
var index = $scope.rateValues.rates.fastrates.value.indexOf(rate);
if (index < 0) {
$scope.rateValues.rates.fastrates.value.push(rate);
} else {
$scope.rateValues.rates.fastrates.value.splice(index, 1);
}
}
});

kik api wont work with angularjs json

I cant seem to make my angularjs code work with the kik api:
var myApp = angular.module('myApp', []);
myApp.controller('MainCtrl', function($scope) {
$scope.go = function() {
kik.send({
title: 'message title',
text : 'Message body',
data : {
color: 'green',
size: 'one' }
});
}
//kik.message is exactly what was provided in kik.send
//in this case: { color: 'green', size: 'one' }
if(kik.message) {
$scope.result = kik.message;
}
});
//html ng-app="my-app"
<div controller="MainCtrl">
<li ng-repeat="todo in result">
{{todo.color}} {{todo.size}}
</li>
</div>
$scope.result should hold the data that was inside "api.oppened", but it seems like I made a mistake.
link to API
Looks like your ng-repeat expects result to be an array but it is instead { color: 'green', size: 'one' }. So when you do todo in result, todo isn't the object that you expect it to be.
Simply change your assignment to result:
if (kik.message) {
$scope.result = [ kik.message ];
}

Multiple custom filters in angular.js

I have a multi check box application which requires me to have multiple filters. I have been unable to use multiple filters even if I try to hard code an array to filter on. Here is an example I have created to try to make this work.
Working Example
HTML MARKUP:
<body ng-app="app">
<div ng-controller="MainCtrl">
<div ng-repeat="item in data.sessions | IndustryFilter : data.sessions.industry ">
{{item.id}}
</div>
</div>
Javascript
var app = angular.module("app", [])
.controller("MainCtrl", function ($scope, MatchedFilterList) {
$scope.data = {"sessions": [{
"id": "a093000000Vhzg7AAB",
"industry": ["Automovtive"],
"sessionName": "Keynote",
},
{
"id": "a093000000zg7AAB",
"industry": ["Automovtive", "Retail"],
"sessionName": "Keynote2",
},
{
"id": "a093er000f00zg7AAB",
"industry": ["Automovtive", "Retail", "Consumer Goods"],
"sessionName": "Keynote3",
}
]};
}).filter("IndustryFilter", function (MatchedFilterList) {
return function () {
var filtered = [];
angular.forEach(MatchedFilterList.industry, function (item) {
filtered.push(item);
});
console.log("Filter: Filter " + filtered)
return filtered;
};
})
.factory("MatchedFilterList", function(){
var matchedFilterList = {};
matchedFilterList.industry = {
"Automotive": "Automotive",
"Retail" : "Retail"
};
return matchedFilterList;
});

Resources