Angular/Ionic ng-repeat + ng-init $scope variable parameter passing - javascript

Im trying to call a function inside ng-init using the result of ng-repeat but the only image displayed is the last image that was pass to the scope variable.
Any tips or suggestion if im doing this correctly?
Template
<ion-item ng-repeat="feed in feeds" ng-if=fbfeed.message ng-init='addAttachment(feed.id)'>
<div class="list card">
<div class="item item-body">
<img src="{{attachment.media.image.src}}">
</div>
</div>
</ion-item>
Controller
$scope.addAttachment = function (postId) {
var attachmentData = MediaManager.getAttachments( postId );
attachmentData.then(function(result) {
if (result.data.length) {
$scope.attachment = result.data[0];
}
});
};

You need to add the attachment field with all the objects . so add that to the object feed .
You can pass the feed id and assign the corresponding image in the function.
HTML
<ion-item ng-repeat="feed in feeds" ng-if=fbfeed.message ng-init='addAttachment(feed)'>
<div class="list card">
<div class="item item-body">
<img src="{{feed.attachment.media.image.src}}">
</div>
</div>
</ion-item>
Controller:
$scope.addAttachment = function (feed) {
var attachmentData = MediaManager.getAttachments( feed.postId );
attachmentData.then(function(result) {
if (result.data.length) {
feed.attachment = result.data[0];
}
});
};

Related

ng-click to affect only the element it is inside

I am using ng-repeat to generate some elements...
<div class="form-block" ng-repeat="form in formblock | filter:dateFilter">
<div ng-click="showResults()" ng-if="repeat == true" class="drop">{{ form.form_name }} <span class="caret"></span></div>
<div ng-show="results" class="formURL">{{ form.url }}</div>
<div ng-show="results" class="formCount">{{ form.count }}</div>
<div ng-show="results" class="formSubmit">{{ form.submit }}</div>
</div>
As you can see, ng-click="showResults()" toggles the display of the other elements. The problem is, I only want the ng-click to toggle the elements inside the same container, not toggle all elements.
In short, I only want the click event to affect the elements in the same container that the function is called, how can I do this?
this is showResults in my controller...
$scope.showResults = function(){
return ($scope.results ? $scope.results=false : $scope.results=true)
}
ng-repeat provides you with a special variable (unless you already have an identfier): $index.
Using this, you can store (instead of a single boolean value) an object $index => toggleState in your angular code:
$scope.hiddenHeroes = {};
$scope.toggleHero = function (idx) {
$scope.hiddenHeroes[idx] = !$scope.hiddenHeroes[idx];
}
And in your HTML:
<div ng-repeat="hero in heroes">
<div class="hero" ng-hide="hiddenHeroes[$index]">
<h1>
{{hero}}
</h1>
All you want to know about {{hero}}!
<br />
</div>
<a ng-click="toggleHero($index)">Toggle {{hero}}</a>
</div>
See it live on jsfiddle.net!
You can use $index to index item/containers and show the corresponding results:
<div ng-click="showResults($index)" ng-if="repeat == true" class="drop">{{ form.form_name }} <span class="caret"></span></div>
<div ng-show="results[$index]" class="formURL">{{ form.url }}</div>
<div ng-show="results[$index]" class="formCount">{{ form.count }}</div>
<div ng-show="results[$index]" class="formSubmit">{{ form.submit }}</div>
And your function
$scope.showResults = function(index){
return ($scope.results[index] ? $scope.results[index]=false : $scope.results[index]=true)
}

AngularJS: Add toggle function to an image inside ng-repeat

I am using ng-repeat for div element. I have a toggle function on image inside div element. However, when I click on image, function gets triggered but it is showing up same data for all divs. Below is the code.
HTML :
<div ng-repeat="item in items">
<div>
<img src="img/icon1.png" class="pull-right" ng-click="showDiv(item.itemId,$index)">
</div>
<div ng-show="hiddenDiv[$index]">
<div ng-repeat="student in studentData">
<div class="row">
<div>
<div>{{student.name}}</div>
<div>{{student.adress}}</div>
</div>
</div>
</div>
</div>
</div>
JS :
$scope.hiddenDiv=[];
$scope.showDiv=function(itemId,index) {
$scope.hiddenDiv[index] = !$scope.hiddenDiv[index];
var myResult = ListService.getList(url here);
myResult.then(function (data) {
if(data && data.list)
$scope.studentData = data.list;
});
}
Here, I am using same scope variable in all divs inside ng-repeat.
Updated Answer :
js :
$scope.studentData = [];
$scope.studentData[index] = data.list;
HTML :
If you want to have unique students for every item, you need to do something like this:
<div ng-repeat="item in items">
<div>
<img src="img/icon1.png" class="pull-right" ng-click="showDiv(item.itemId,$index)">
</div>
<div ng-show="hiddenDiv[$index]">
<div ng-repeat="student in item.studentData">
<div class="row">
<div>
<div>{{student.name}}</div>
<div>{{student.adress}}</div>
</div>
</div>
</div>
</div>
</div>
and js:
$scope.hiddenDiv=[];
$scope.showDiv=function(itemId,index) {
$scope.hiddenDiv[index] = !$scope.hiddenDiv[index];
var myResult = ListService.getList(url here);
myResult.then(function (data) {
if(data && data.list)
$scope.items[index].studentData = data.list;
});
}
or use the same as for hiddenDiv
$scope.hiddenDiv=[];
$scope.studentData = [];
$scope.showDiv=function(itemId,index) {
$scope.hiddenDiv[index] = !$scope.hiddenDiv[index];
var myResult = ListService.getList(url here);
myResult.then(function (data) {
if(data && data.list)
$scope.studentData[index].studentData = data.list;
});
}
and html:
<div ng-repeat="student in studentData[$index]">

Access object properties from template to function - Angular

Simply, I have an array of objects, [images], that I display perfectly fine on Ng-repeat. When I click one div, I want to see the 'id' property of the particular image that was clicked on in the template.
Function in controller:
angular.forEach(value, function (value, key) {
$scope.images.push({
id: i,
src: ("data:image/jpeg;base64," + value)
});
i = i + 1;
}
$scope.seeOne = function () {
console.log(image.id);
}
My template:
<div id="galscrolldiv" ng-repeat="image in images">
<div ng-click="seeOne()">
<img ng-src="{{images[$index].src}}" width="100%" />
</div>
</div>
Send the image as parameter from the view/template. Then you can access the image properties of the clicked image.
You've missed the ) of forEach.
Controller:
angular.forEach(value, function (value, key) {
$scope.images.push({
id: i,
src: ("data:image/jpeg;base64," + value)
});
i = i + 1;
});
// Get the parameter i.e. image that is clicked
$scope.seeOne = function (image) {
console.log(image.id);
};
View/Template:
<div id="galscrolldiv" ng-repeat="image in images">
<div ng-click="seeOne(image)">
<!-- ^^^^^-->
<img ng-src="{{images[$index].src}}" width="100%" />
</div>
</div>
You can also send the $index property from template
<div id="galscrolldiv" ng-repeat="image in images">
<div ng-click="seeOne($index)">
<!-- ^^^^^-->
<img ng-src="{{images[$index].src}}" width="100%" />
</div>
</div>
Then inside the controller
$scope.seeOne = function (index) {
console.log($scope.images[index].id);
};
But this may cause issue while using filter.
So in case of using filter avoid $index.

angularjs - Trouble getting data from database within template file

I'm working on a blog like structured web app In AngularJS. Im trying to retrieve the user which is an other of a post and retrieve their display name dynamically as it loops through all the posts but I cant seem to retrieve data correctly.. This is what I have done so far.
Blog Controller:
uno.controller('newsCtrl', function($scope, $http, adbFactory){
$scope.derp = 'derp!!!!!';
adbFactory.get($http, 'get users 1', false).success(function(data){
$scope.user = data;
}).error(function(){
console.log('Errorrr');
});
$scope.init = function(){
adbFactory.get($http, 'get all blog_posts', true).success(function(data){
$scope.posts = data;
console.log($scope.posts);
});
};
$scope.getAuthor = function(_id) {
adbFactory.get($http, 'get users id ' +_id+ ' spec', false).success(function(data){
//$scope.author = data;
//console.log($scope.author);
return data;
});
};
});
If I console.log the data it shows the users perfectly given the author id which is in the database, but when i attempt to call the getAuthor function using the '{{ }}' scope i get a collage of errors... heres my blog template below.
Blog Template:
<div class="large-12 small-12 columns" ng-init="init()">
<div class="row">
<div class="large-12 small-12 columns" ng-repeat="topic in posts" style="margin-bottom:20px;">
<div id="news-post" class="panel animated fadeInUp">
<div class="row" ng-init="getAuthor(topic.author_id)">
<div class="large-2 small-2 columns">
<img src="{{ topic['thumb'] }}" alt="" style="border-radius:50%; height:100px; width: 150px;" />
</div>
<div class="left large-10 small-10 columns">
<div class="row">
<h2 class="post-title">{{topic['title']}} <p>Posted By, {{ getAuthor(topic.author_id).email }}</p></h2>
<p>{{ topic['body'] }}</p>
</div>
</div>
</div>
</div>
</div>
<hr>
</div>
</div>
not quite sure what the problem can be.. Any thing I'm missing?
UPDATE::
I recently updated my controller and factories to get a better scope of handling my data flow, my Controller now looks like this:
uno.controller('newsCtrl', function($scope, $http, adbFactory, $cacheFactory, unoFunctions){
$scope.init = function(){
adbFactory.get($http, 'get all blog_posts', true).success(function(data){
$scope.posts = data;
$scope.getUser = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
//console.log($scope.userData);
return $scope.userData;
};
});
$scope.getTags = function(_id) {
var post = unoFunctions.getPost(_id);
var _tags = post.tags.split(',');
for(var i = 0; i < _tags.length; i++)
{
_tags[i] = _tags[i].trim();
}
return _tags;
};
$scope.getUserName = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
return $scope.userData.display_name;
};
$scope.getUser = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
//console.log($scope.userData);
return $scope.userData;
};
$scope.getUserName = function(_id) {
$scope.userData = unoFunctions.getUser(_id);
return $scope.userData.display_name;
};
};
});
the unoFunctions factory is wht I use now to handle certain requests from my database, and that is shown below.
uno.factory('unoFunctions', function(adbFactory, $http, $cacheFactory){
var fact = {};
var user = $cacheFactory('user');
var post = $cacheFactory('post');
fact.getUser = function(_id) {
if(!user.get(_id)){
adbFactory.get($http, 'get users id '+_id+' spec', false).success(function(data){
user.put(_id, data);
});
}
return user.get(_id);
};
fact.getPost = function(_id) {
if(!post.get(_id))
{
adbFactory.get($http, 'get blog_posts id '+_id+' spec', false).success(function(data){
post.put(_id, data);
});
}
return post.get(_id);
};
fact.loggedIn = function()
{
console.log('gfdg');
};
/*------------------------------*/
return fact;
});
And my template to output the result is this:
<div class="large-12 small-12 columns" ng-init="init()">
<div class="row">
<div class="large-12 small-12 columns" ng-repeat="topic in posts | filter:postTitle | orderBy:'-time' " style="margin-bottom:20px;">
<div id="news-post" class="panel animated fadeInUp" ng-init="getTags(topic.id)">
<div class="row" style="padding-bottom:0px;">
<div class="large-2 small-2 columns">
<img src="{{ topic['thumb'] }}" alt="" style="border-radius:50%; height:120px; width: 200px;" />
</div>
<div class="left large-10 small-10 columns">
<div class="row" style="padding-bottom:0px;">
<h2 class="post-title">
<a href="#/news/post/{{ topic['id'] }}">
{{topic['title']}}
</a>
<p style="font-size:13px; font-style:italic; color:#a5a5a5" class="right">{{ topic.time | timeago }} {{ }}</p>
<p style="font-weight:bold; font-style:italic; color:#aaa">Posted By, {{ getUser(topic.author_id).display_name }}</p></h2>
<p>{{ topic['body'] }}</p>
<div ng-repeat="tag in getTags(topic.id)"><span style="background:#ccc; margin:7px; padding:4px; border-radius:5px; font-size:12px" class="left">{{ tag }}</span></div>
<p class="right" style="background:#dedede; font-size:13px; padding:7px; border-radius:6px; color:#1985A1;">{{ topic.category }}</p
</div>
</div>
</div>
</div>
</div>
</div>
</div>
This works fine and returns the required results I'm looking for but I wish to get rid of the countless Error: [$rootScope:infdig] errors and keep my console clean.. I researched the error and it seems to be because when I call functions from the unoFunctions factory like, getUser, or getPost. it returns a new array each time or something like that which I guess throws things out of scope. I'm not entirely sure, and reason for this?
This binding
<p>Posted By, {{ getAuthor(topic.author_id).email }}</p>
assumes that getAuthor returns an object, but it doesn't, even with proper return statement - because asynchronous request takes place, and adbFactory chain will apparently return a promise, not an object. And doing adbFactory.get every time getAuthor bindings are being watched would be bad performance-wise - json result has to be parsed constantly, even with $http cache.
A suitable solution for caching and binding service results to the scope (and a precursor to full-blown model) is
var authors = $cacheFactory('authors');
$scope.getAuthor = function(_id) {
if (!authors.get(_id)) {
authors.put(_id, {});
adbFactory.get($http, 'get users id ' +_id+ ' spec', false).success(function(data){
authors.put(_id, data);
});
}
return authors.get(_id);
};

Adding objects to the DOM after adding new data to the list

I have an array of objects which i populate on a button click.
When populating this array i make sure that i only add 10 objects to it.
When this is all loaded in the dom i give the user the oppertunity to add a few more objects.
I do this like this:
$scope.Information = [];
$.each(data, function (i, v) {
if (i<= 9)
$scope.Information.push(data[i]);
if(i >= 10) {
cookieList.push(data[i]);
}
}
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
$(".showMore").removeClass("hidden");
}
$(".showMore").on("click", function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
});
part of the HTML:
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
My issue: When i add objects to my array of objects "$scope.Information.push(obj);" I assumed that they would get added in the DOM but they do not, how do i do this the angular way?
EDIT MY SOLOUTION:
edited the HTML to use ng-click and the method is as follows:
$scope.addMore = function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
SetSpinner('show');
$.each(obj, function(i,v) {
$scope.Information.push(v);
});
SetSpinner('hide');
}
Here is the angular way:
 The view
<!-- Reference your `myapp` module -->
<body data-ng-app="myapp">
<!-- Reference `InfoController` to control this DOM element and its children -->
<section data-ng-controller="InfoController">
<!-- Use `ng-click` directive to call the `$scope.showMore` method binded from the controller -->
<!-- Use `ng-show` directive to show the button if `$scope.showMoreButton` is true, else hide it -->
<button data-ng-click="showMore()" data-ng-show="showMoreButton">
Show more
</button>
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
The module and controller
// defining angular application main module
var app = angular.module('myapp',[])
// defining a controller in this module
// injecting $scope service to the controller for data binding with the html view
// (in the DOM element surrounded by ng-controller directive)
app.controller('InfoController',function($scope){
$scope.Information = [];
$scope.showMoreButton = false;
// Bind controller method to the $scope instead of $(".showMore").on("click", function() {});
$scope.showMore = function(){
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
};
$.each(data, function (i, v) {
if (i<= 9) $scope.Information.push(data[i]);
if(i >= 10) cookieList.push(data[i]);
});
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
//$(".showMore").removeClass("hidden");
$scope.showMoreButton = true; // use $scope vars and ng-class directive instead of $(".xyz").blahBlah()
}
});
You should not use JQuery, use ng-click to detect the click, because angular has no idea when JQuery is done and when it needs to refresh the interface

Categories

Resources