AngularJS ng-click not responding when clicked - angularjs

I know there is alot of questions about this topic out there, but could not find any solution to my problem. My code:
UPDATE
$scope.openOne = function (id) {
ImageService.getDetails(id).then(function (data) {
$scope.imageDetail = data;
}).catch(function (e) {
var message = [];
});
}
function getAllImages() {
ImageService.getImages().then(function (value) {
$scope.images = value;
var items = [];
$(value).each(function () {
var url = "https://someUrl/" + this.Image[0];
console.log(url);
items.push(`
<tr>
<td><button id="button" ng-click="openOne(${this._id})">${this.ImageName}</button></td>
<td>${this.ImageCategory}</td>
<td>
<img style="width:30%;" ng-src="${url}" alt="The Image is missing">
</td>
</tr>
`);
});
$("#body").append(items.join(''));
}).catch(function (e) {
var message = [];
}).finally(function (e) {
});
}
I am creating the button in in the controller and then appending it to the DOM.
Does anybody see the error? When I click the button nothing happens.

Approach is all wrong.
The fundamental principal in angular is let your data model drive the view and let angular compile that view from templates
A more typical set up would pass your images array to ng-repeat in the view:
Controller:
function getAllImages() {
ImageService.getImages().then(function (value) {
$scope.images = value;
});
}
View:
<tr ng-repeat="img in images track by $index">
<td><button id="button" ng-click="openOne(img.id)">{{img.ImageName}}</button></td>
<td>{{img.ImageCategory}}</td>
<td>
<img style="width:30%;" ng-src="{{img.url}}" alt="The Image is missing">
</td>
</tr>

You need to add $compile service here, that will bind the angular directives like ng-click to your controller scope. For example
app.controller('yourController', function($scope,$compile) {
var button = '<button id="button" ng-click="openOne(${this._id})">${this.ImageName}</button>';
items.push(button);
$("#body").append(items.join(''));
var temp = $compile(button)($scope);
$scope.openOne = function(){
alert('Yes Click working at dynamically added element');
}
});

Related

Array Push not working with Real Time

I'm using Pusher for Angular Webapp for Real Time Application. I need add to array products a new item when other add a item from form in other session. In my sessiĆ³n it's works. In another session the data obtained if it is added to the array but not shown in the ng-repeat.
Controller:
.controller('MainCtrl', ['$scope','Products',function($scope,Products) {
$scope.products = Products.getAll();
var pusher = new Pusher('MY KEY', {
encrypted: true
});
$scope.addProduct = function(product){
Products.addProduct(product);
}
var callback = function(data) {
$scope.products.push(data.NewProduct);
console.log($scope.products);
};
var channel = pusher.subscribe('products');
channel.bind('addProduct', callback);
}]);
View:
<tbody>
<tr ng-repeat="product in products track by product.id">
<td >{{product.name}}</td>
<td>{{product.unity}}</td>
<td>{{product.price}}</td>
<td>
<button>
Edit
</button>
<button>
Delete
</button>
</td>
</tr>
</tbody>
$evalAsync Executes the expression on the current scope at a later point in time.
So add $evalAsync to callback function in your code
.controller('MainCtrl', ['$scope','$evalAsync','Products',function($scope,$evalAsync, Products) {
$scope.products = Products.getAll();
var pusher = new Pusher('MY KEY', {
encrypted: true
});
$scope.addProduct = function(product){
Products.addProduct(product);
}
var callback = function(data) {
$scope.products.push(data.NewProduct);
console.log($scope.products);
};
var channel = pusher.subscribe('products');
channel.bind('addProduct', $evalAsync(callback));
}]);
I did it like this:
var callback = function(data) {
$scope.$apply(function(){
$scope.products.push(data.Producto);
});
console.log($scope.products);
};

Angular 1.6: Data not showing until scope function execute

Title might sound a bit strange but that's how it is.
Code:
angular.module('app')
.controller('TenantsCtrl', ['$scope', 'tenantsService','$window','loginService', function ($scope, tenantsService, $window, loginService) {
$scope.mode = "list";
$scope.g = [];
$scope.editTenant = {
firstName: "",
lastName: "",
room: "",
to: "",
from: ""
}
tenantsService.get().then((data) => {
data.tenants.map((tenant) => {
tenant.to = new Date(tenant.to).toLocaleDateString('ro-RO')
tenant.from = new Date(tenant.from).toLocaleDateString('ro-RO')
});
console.log(typeof data.tenants);
$scope.g = data.tenants;
console.log($scope.g)
}).catch((reason) => {
loginService.doLogout();
if(confirm(`${reason}. Please login`)) {
$window.location.href="#!/login";
}
})
$scope.showTenantForm = function(tenant) {
console.log($scope.g)
}
}]);
View:
<div class="page-header">
<h1>Cazati <button class="btn btn-xs btn-primary" ng-click="showTenantForm()">Cazeaza</button></h1>
</div>
<div class="row" ng-cloak>
{{g}}
<table class="table table-hover">
<thead>
<tr>
<th>Nume</th>
<th>Camera</th>
<th>Cazat din</th>
<th>Cazat pana la</th>
<th>Cazat de</th>
<!--<th>Status</th>-->
<th>Modifica</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="x in g">
<td>{{x.lastName}} {{x.firstName}}</td>
<td>{{x.room}}</td>
<td>{{x.to}}</td>
<td>{{x.from}}</td>
<td></td>
<td>
<button type="button" ng-click="editTenant(tenant.id)" class="btn btn-danger btn-xs">Modifica</button>
</td>
</tr>
</tbody>
</table>
</div>
Problem: data from table isn't shown. Strangely it gets shown only when press the button from header and the function gets called.
Data from service comes correctly.
Update: tenantsService
angular.module('app')
.service('graphQLService', ['baseUrl', 'loginService', function (baseUrl, loginService) {
var graphQLService = {};
graphQLService.sendQuery = function (query, vars) {
var self = this;
vars = vars || {};
return new Promise(function(resolve, reject) {
// use fetch to get the result
fetch(baseUrl + '/gql', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
query,
vars,
authToken: loginService.getToken()
})
})
.then(function(response) {
var status = response.status;
if(status != 401) {
return response.json().then((res) => {
resolve(res.data);
})
} else {
reject(response.statusText);
}
if(response.status == 401) {
}
})
.catch(reject);
});
};
return graphQLService;
}]);
Add a $scope.$apply() after you get your response and you manipulate your data, and after that you assign your data to your g scope variable. So:
$scope.g = data.tenants;
$scope.$apply();
AngularJS already wraps a lot of its code inside the $scope.$apply method. This in order to trigger the $scope.$digest method, which is the one responsible for refreshing all the bindings inside the related scope and update the values and so the views.
For example, if you were using the custom $http service, it's executed inside the $scope.$apply, so you don't need to call it explicitly.
In your case, you are not using the standard $http, so you need to trigger it manually.
The code was working after calling the other function because the ng-click is wrapped inside the $apply as well, so it refreshes all the bindings in the scope.
If you want to read more about it, this is a pretty good article:
http://jimhoskins.com/2012/12/17/angularjs-and-apply.html
I hope it helps
I think the problem is that data.tenants.map returns you a new array. You don't save the reference to it.
Have you tried to do this
$scope.g = data.tenants.map((tenant) => {
tenant.to = new Date(tenant.to).toLocaleDateString('ro-RO');
tenant.from = new Date(tenant.from).toLocaleDateString('ro-RO');
return tenant;
});
console.log(typeof data.tenants);
console.log($scope.g)

$scope variable is undefined in post

I have AngularJS repeat biaya in data_biaya that I have from JSON.
When I ng-click="simpan_biaya(data_biaya)", why is the data posting undefined?
<input type="button" ng-click="simpan_biaya(data_biaya)" value="Simpan"/>
<tr ng-repeat="biaya in data_biaya | filter:{tahapan_id : 10}" >
<td>{{$index+1}}</td>
<td><span >{{biaya.tanggal_transaksi}}</span></td>
<td><span>{{biaya.uraian}}</span></td>
<td><span>{{biaya.pihak_nama}}</span></td>
<td><span >{{data_biaya[$index].pemasukan}}</span></td>
<td><span>{{biaya.pengeluaran}}</span></td>
<td>{{biaya.sisa}}</td>
<td><span >{{biaya.keterangan}}</span></td>
</tr>
JavaScript
var datanya=[
{"id":"23713","id_pembiayaan":"1","perkara_id":"7200","tahapan_id":"10","kategori_id":"1","jenis_biaya_id":"1","pihak_id":null,"pihak_ke":null,"urutan":"1","jenis_transaksi":"1","tanggal_transaksi":"2016-05-26","uraian":"Panjar Biaya Perkara","pemasukan":1000000,"pengeluaran":0,"jumlah":1000000,"sisa":1000000,"keterangan":null,"pihak_nama":"Penggugat"},
{"id":"23714","id_pembiayaan":"1","perkara_id":"7200","tahapan_id":"10","kategori_id":"11","jenis_biaya_id":"61","pihak_id":null,"pihak_ke":null,"urutan":"2","jenis_transaksi":"-1","tanggal_transaksi":"2016-05-26","uraian":"Biaya Pendaftaran\/PNBP","pemasukan":0,"pengeluaran":"30000.00","jumlah":"30000.00","sisa":970000,"keterangan":null,"pihak_nama":"Penggugat"}
];
var app = angular.module('jurnalApp', []);
app.controller('jurnalCtrl', function($scope,$http) {
$scope.data_biaya = [];
$scope.searchClick = function (data) {
$scope.$apply(function(){
$scope.data_biaya=datanya;
});
};
$scope.simpan_biaya = function(data){
var post_data = data;
$.post("<?php echo base_url().'all_jurnal/set_jurnal_biaya';?>", post_data)
.done(function(json){
});
}
angular.element(document).ready(function () {
$scope.searchClick();
});
});
Here: plunker
Try this:
<input type="button" ng-click="simpan_biaya(data_biaya)" value="Simpan"/>
DEMO
Based on the attached screenshot, you should pass JSON data, convert the data to JSON before passing:
var dataJson=angular.toJson(post_data);
you should use that:
var post_data = data; var dataJson=angular.toJson(post_data); $.post("
<?php echo base_url().'all_jurnal/set_jurnal_biaya';?>", dataJson ) .done(function(json){ });

RestAngular Put request in AngularJs

How can I make a put request in RestAngular?
This is what I tried.
facUpdatePartner: function (partner)
{
var url = "UpdatePartner";
var result = Restangular.one(url);
return result.put(partner);
}
I don't know you full code but should is something like this:
facUpdatePartner: function (partner)
{
return partner.put();
}
the partner need to come from a previous getOne or a get with Restangular. For example:
Controller:
vm.getCategories = function () {
Category.get().then(function (categories) {
vm.categories = categories;
});
};
vm.getCategories();
vm.update = function(category){
category.put().then(function(result){
alert('UPDATED!');
}).catch(function(err){
alert('ERROR!');
});
};
HTML:
...
<tr ng-repeat="category in vm.categories">
<td>
<input type="text" ng-model="category.name">
</td>
<td>
<button type="button" ng-click="vm.update(category)">
</td>
</tr>
....

How to remove deleted row in ng-table

I have a grid developed using ng-table and I need to remove selected item from grid table after removing from server-side. Already tried to call the grid loading ajax again, but it's not working.
My Controller,
app.controller('blockController', function($scope, $filter, $q, ngTableParams, $sce, Block) {
// Fetch data from server using RESTful API
$scope.load = function() {
// load serverside data using http resource service
Block.get({}, function (response) { // success
$scope.results = response.data;
var data = response.data; // store result to variable
// Start ng-table with pagination
$scope.tableParams = new ngTableParams({
page: 1, // show first page
count: 10 // count per page
}, {
total: data.length, // length of data
getData: function($defer, params) {
// use build-in angular filter
var orderedData = params.sorting() ? $filter('orderBy')(data, params.orderBy()) : data;
orderedData = params.filter() ? $filter('filter')(orderedData, params.filter()) : orderedData;
params.total(orderedData.length); // set total for recalc pagination
$defer.resolve($scope.blocks = orderedData.slice((params.page() - 1) * params.count(), params.page() * params.count()));
}
});
// un-check all check boxes
$scope.checkboxes = { 'checked': false, items: {} };
// watch for check all checkbox
$scope.$watch('checkboxes.checked', function(value) {
angular.forEach($scope.blocks, function(item) {
if (angular.isDefined(item.id)) {
$scope.checkboxes.items[item.id] = value;
}
});
});
// watch for data checkboxes
$scope.$watch('checkboxes.items', function(values) {
if (!$scope.blocks) {
return;
}
var checked = 0, unchecked = 0,
total = $scope.blocks.length;
angular.forEach($scope.blocks, function(item) {
checked += ($scope.checkboxes.items[item.id]) || 0;
unchecked += (!$scope.checkboxes.items[item.id]) || 0;
});
if ((unchecked == 0) || (checked == 0)) {
$scope.checkboxes.checked = (checked == total);
}
// grayed checkbox
angular.element(document.getElementById("select_all")).prop("indeterminate", (checked != 0 && unchecked != 0));
}, true);
}, function (error) { // error
$scope.results = [];
// error message display here
});
}
// Call REST API
$scope.load();
/*
|------------------------------
| Delete selected items
|------------------------------
*/
$scope.delete = function() {
var items = [];
// loop through all checkboxes
angular.forEach($scope.blocks, function(item, key) {
if($scope.checkboxes.items[item.id]) {
items.push(item.id); // push checked items to array
}
});
// if at least one item checked
if(items.length > 0) {
// confirm delete
bootbox.confirm("Are you sure to delete this data?", function(result) {
if(result==true) {
for (var i = 0; i < items.length; i++) {
// delete using $http resopurce
Block.delete({id: items[i]}, function (response) { // success
// remove the deleted item from grid here
// show message
}, function (error) { // error
// error message display here
});
}
}
});
}
}; // delete
}); // end controller
HTML Table,
<!-- data table grid -->
<table cellpadding="0" cellspacing="0" border="0" class="table table-striped table-bordered" ng-table="tableParams" show-filter="true">
<tbody>
<tr ng-repeat="block in $data">
<!-- serial number -->
<td data-title="'<?php echo $this->lang->line('sno'); ?>'" style="text-align:center" width="4">{{$index+1}}</td>
<!-- Checkbox -->
<td data-title="''" class="center" header="'ng-table/headers/checkbox.html'" width="4">
<input type="checkbox" ng-model="checkboxes.items[block.id]" />
</td>
<!-- Block Name -->
<td data-title="'<?php echo $this->lang->line('label_cluster_name'); ?>'" sortable="'block_name'" filter="{ 'block_name': 'text' }">
<span ng-if="!block.$edit">{{block.block_name}}</span>
<div ng-if="block.$edit"><input class="form-control" type="text" ng-model="block.block_name" /></div>
</td>
<!-- Description -->
<td data-title="'<?php echo $this->lang->line('label_description'); ?>'" sortable="'description'" >
<span ng-if="!block.$edit">{{block.description}}</span>
<div ng-if="block.$edit"><textarea class="form-control" ng-model="block.description"></textarea></div>
</td>
<!-- Edit / Save button -->
<td data-title="'<?php echo $this->lang->line('label_actions'); ?>'" width="6" style="text-align:center">
<a ng-if="!block.$edit" href="" class="btn btn-inverse btn-sm" ng-click="block.$edit = true"><?php echo $this->lang->line('label_edit'); ?></a>
<a ng-if="block.$edit" href="" class="btn btn-green btn-sm" ng-click="block.$edit = false;update(block)"><?php echo $this->lang->line('label_save'); ?></a>
</td>
</tr>
</tbody>
</table> <!-- table grid -->
You should remove the deleted item from the data collection once the server confirms the deletion.
You can do this manually from within the delete success callback instead of just reloading the complete collection (which is theoretically valid as well but will often be slower).
Then after removing the item from the collection, call the tableParams.reload() method to reload the table so the change is reflected in the table.
You can find a working example of the reload() method right here: http://plnkr.co/edit/QXbrbz?p=info
Hope that helps!
This is working for me:
$scope.deleteEntity = function (entity) {
bootbox.confirm("Are you sure you want to delete this entity ?", function (confirmation) {
if (confirmation) {
$http.delete("/url/" + entity._id)
.success(function (data) {
if (data.status == 1) {
var index = _.indexOf($scope.data, entity);
$scope.data.splice(index, 1);
$scope.tableParams.reload();
} else {
}
});
}
}
);
};
In version 1x of ng-table the following code works. In this example I'm using the MyController as vm approach and user is a $resource class object:
this.removeUser = function (user,i) {
user.$remove().then(function () {
this.tableParams.data.splice(i, 1);
}, function () {
// handle failure
});
});
When called in your HTML table, be sure to pass in $index as the second parameter, eg:
<button class="btn btn-danger btn-xs" ng-click="vm.removeUser(user, $index)" title="Delete User">
<i class="glyphicon glyphicon-trash"></i>
</button>
No need to call tableParams.reload or reload data from the server.

Resources