AngularJS update data in ng-repeat from http request - javascript

I searched for solution but I didn't found an answer. What is my problem, on my category view I have init function which makes http request and get all category from database. I use that records and make ng-repeat. But when I open modal with form to make new category I can't update that ng-repeat view when modal close and see new category. I organize my controller, service and view in this way:
view
<div class="row main-body no-padding" ng-init="adminCtr.initCategory()">
<div class="col-lg-4 margin-bottom-20" ng-repeat="category in adminCtr.allCategories">
<div class="header-panel">
<span class="category-headline">{{category.name}}</span>
</div>
<div class="main-form">
{{category.id_cat}}
</div>
</div>
</div>
controller:
function addCategory() {
$mdDialog.show({
templateUrl: 'app/views/modal/addCategory.html',
clickOutsideToClose: false,
controller: 'adminController',
controllerAs: 'adminCtr'
});
}
function initCategory() {
adminService.initCategory().then(function (data) {
vm.allCategories = data.categories;
})
}
function createCategory(category) {
adminService.createCategory(category).then(function (data) {
if(data.success == false) {
vm.categoryError = data.error;
} else {
vm.categoryError = '';
cancelModal();
initCategory();
$location.path('/admin/category');
$timeout(function () {
$mdToast.show(
$mdToast.simple()
.textContent('Kategorija je uspešno kreirana')
.position('top right')
.theme("success-toast")
.hideDelay(5000)
);
}, 500);
}
})
}
function cancelModal() {
$mdDialog.hide();
}
service:
function createCategory(category) {
return $http.post('api/admin/createCategory', {
category: category,
idUser: $rootScope.globals.currentUser.idUser,
token: $rootScope.globals.currentUser.token
}).then(function(response) {
return response.data;
});
}
function initCategory() {
return $http.post('api/admin/getAllCategories', {
idUser: $rootScope.globals.currentUser.idUser,
token: $rootScope.globals.currentUser.token
}).then(function(response) {
return response.data;
});
}
I tried to call again init function to update vm.allCategories but without any success.
Does any know some solution?
P.S. I tried with $scope.apply() but I got error, btw I use angular 1.6.2.

in the service remove the promise. you are caching the response in the controller using promise. So need to add a promise in the service also.
function initCategory() {
return $http.post('api/admin/getAllCategories', {
idUser: $rootScope.globals.currentUser.idUser,
token: $rootScope.globals.currentUser.token
})
}
in the controller update like this
function initCategory() {
adminService.initCategory().then(function (res) {
vm.allCategories = res.data.categories; // in the response data comes inside data property.
})
}

Change your HTML template like below:
<div class="col-lg-4 margin-bottom-20" ng-repeat="category in adminCtr.allCategories track by category.id_cat">
and your JS
function initCategory() {
adminService.initCategory().then(function(data) {
$scope.$evalAsync(function(){
vm.allCategories = data.categories;
});
})
}
Demo
angular.module('myApp', []);
angular
.module('myApp')
.controller('MyController', MyController);
MyController.$inject = ['$scope', '$timeout'];
function MyController($scope, $timeout) {
var vm = this;
var a = [{
"id_cat": "1",
"name": "fgfdgfd"
}, {
"id_cat": "2",
"name": "dfgfdgdf"
}, {
"id_cat": "3",
"name": "dfgfdgdffdgdfg"
}];
var b = [{
"id_cat": "1",
"name": "fgfdgfd"
}, {
"id_cat": "2",
"name": "dfgfdgdf"
}, {
"id_cat": "3",
"name": "dfgfdgdffdgdfg"
}, {
"id_cat": "4",
"name": "dfgfdgdfg"
}, {
"id_cat": "5",
"name": "dfdsfsdfsdfsd"
}, {
"id_cat": "6",
"name": "sdfdsfsdfsdfsdfsd"
}, {
"id_cat": "7",
"name": "dfgfdgfgfgfdgdf"
}];
vm.allCategories = a;
$timeout(function() {
$scope.$evalAsync(function() {
vm.allCategories = b;
});
}, 2000);
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
<div ng-app="myApp" ng-controller="MyController as vm">
<div ng-repeat="category in vm.allCategories track by category.id_cat">
{{category.name}}
</div>
</div>

Related

Merge multiple json with the same id

the first json is coming from the API in get this data by making a http call
[
{
"clientid": 1,
"clientname": "facebook",
"forecasted": 18,
},
{
"clientid": 2,
"clientname": "youtube",
"forecasted": 83,
}
]
i create the second json to update the image on the first json
[
{
"clientid": 1,
"clientname": "facebook ",
"img":"images/21747.jpg"
},
{
"clientid": 2,
"clientname": "youtube",
"img": "images/youtube.svg"
},
]
now i need to macth both json base on the same id, and fill the first json that i coming from the api with images of the second json
app.factory('myFactory', function($http){
return{
client: function(callback){
$http({
method: "GET",
url: "http://www.erek.co.za/api/..",
cache:true
}).then(callback);
},
list: function(callback){
$http({
method: "GET",
url: "data/Client.json",
cache:true
}).then(callback);
}
};
});
app.controller('myController', function ($scope, myFactory) {
myFactory.client(function(response){
var data = response.data;
$scope.myClients = data;
})
myFactory.list(function (response) {
var data = response.data;
$scope.dark = data;
})
});
html
<div ng-repeat="client in myClients>
<a href="#{{client.clientid}}"
<div class="client-project-panel">
<div class="client-logo-container">
<div class="client-logo" >
<img ng-src="{{dark[$index].img}}" alt="{{client.clientname}}">
</div>
<div class="project-forecasted">
<h2 class="forecasted-value">{{client.forecasted}}%</h2>
<p>Complete</p>
</div>
</div>
</div>
</a>
You can use Object.assign method.
let array1=[ { "clientid": 1, "clientname": "facebook", "forecasted": 18, }, { "clientid": 2, "clientname": "youtube", "forecasted": 83, } ]
let array2 = [ { "clientid": 1, "clientname": "facebook ", "img":"images/21747.jpg" }, { "clientid": 2, "clientname": "youtube", "img": "images/youtube.svg" } ]
var expected = array1.map(a => Object.assign(a, array2.find(b => b.clientid == a.clientid)));
console.log(expected);
myFactory.client(function(response){
var data = response.data;
var clientsData = data;
// after you fetch the clients get list of images
myFactory.list(function (response) {
var data = response.data;
var clientImages = {}
for(var i=0;i<data.length;i++){
clientImages[data[i].clientid] = data[i].img
}
$scope.dark = clientImages
$scope.myClients = clientsData
})
})
In your template just refer to {{dark[client.clientid]}}
You might want to wrap your html in ng-if="myClients" so that the content is shown only after the data is fetched

Change Image when Page Refresh in angularJS

This is on of tough task that am facing in my school. am totally new to angularJs. i need to fetch one image out of all retrieved images from the database. And then when i refresh the page the next image want to appear.
for an example first "banner.jpg" appear when i refresh the page "banner1.jpg" want to appear. can anyone help me to do solve this problem. please.
This is my retrieved Json
{
"id": 1,
"path": "Content/Banner/banner.jpg"
},
{
"id": 2,
"path": "Content/Banner/banner1.jpg"
},
{
"id": 3,
"path": "Content/Banner/banner2.jpg"
},
{
"id": 4,
"path": "Content/Banner/banner3.jpg"
},
my angular controller.
appGM.controller('bannerCtrl', ['$scope', '$http', 'urls', function ($scope, $http, urls) {
var request = $http({
method: 'GET',
url: urls.api + 'Banner/Banners'
}).success(function (data, status) {
console.log(data);
console.log(JSON.stringify(data));
console.log(JSON.parse(JSON.stringify(data)));
$scope.BBanner = angular.fromJson(data);
})
.error(function (error) {
$scope.status = 'Unable to load dog images: ' + error.message;
console.log($scope.status);
});
And its my Html
<div class="row">
<div class="col-sm-3 sidenav" ng-repeat="d in BBanner">
<img ng-src="{{d.path}}">
</div>
you can use localstorage to store the in in the first time. After you refresh the page increment the value and save it to the same local storage and so on.
run this Demo multiple time to see the id change.
controller
if(!localStorage.getItem("uID")){
var s = {"id":1};
localStorage.setItem("uID", JSON.stringify(s))
}
$scope.data = [{
"id": 1,
"path": "Content/Banner/banner.jpg"
},
{
"id": 2,
"path": "Content/Banner/banner1.jpg"
},
{
"id": 3,
"path": "Content/Banner/banner2.jpg"
},
{
"id": 4,
"path": "Content/Banner/banner3.jpg"
}]
var item = localStorage.getItem("uID")
item = JSON.parse(item);
alert("Id = " + item.id)
item.id = item.id +1 ;
localStorage.setItem("uID", JSON.stringify(item))
$scope.clear = function(){
localStorage.removeItem("uID");
}
updated
add this to check the image. check the demo again
var item = localStorage.getItem("uID")
item = JSON.parse(item);
var obj = $scope.data.find(function(o){
return o.id === item.id
})
// add this lines
$scope.image =(obj)? obj.path : "invalid id";
if(item.id == 4){
localStorage.removeItem("uIDs");
item.id = 0;
}
item.id = item.id +1 ;

Filter for search result with AngularJS

A quick question:
I'm creating a filter in angularjs to get dynamically a variable and to be used like this from frontend.
<div ng-if="(services | searchValue : 'type' : 'facebook').active == true">
...
</div>
This is the javascript.
.filter('searchValue', function () {
return function (array, name_var, value) {
angular.forEach(array, function(v, k) {
if (v[name_var] == value) {
return v;
}
});
return [];
};
})
Unfortunately even if the result was found it wasn't passed to the template.
If I'll use it like this:
{{(services | searchValue : 'type' : 'facebook')}}
This will get no value. Any suggestion?
I've created a sample example for the info you've provided. Run the below example check. Hope this helps you.
I guess ng-if itself expects only the variable and not the expression. only provide the variable with value i.e (services | searchValue : 'type' : 'facebook').active not the expression.
var app = angular.module('application', []);
app.filter('customfilter', function() {
return function(array, name_var, value) {
var filteredArray = {};
angular.forEach(array, function(v, k) {
if (v[name_var] == value) {
filteredArray = v;
return false;
}
});
return filteredArray;
}
});
app.controller('sampleController', function($scope, $filter) {
$scope.data = [{
"type": "facebook",
"active": false
}, {
"type": "linkedin",
"active": false
}, {
"type": "twitter",
"active": false
}, {
"type": "google",
"active": false
}];
$scope.anotherdata = [{
"type": "facebook",
"active": true
}, {
"type": "linkedin",
"active": false
}];
});
<script data-require="angular.js#1.3.x" src="https://code.angularjs.org/1.3.17/angular.js" data-semver="1.3.17"></script>
<body ng-app="application">
<div ng-controller="sampleController">
First div - Active : false
<div ng-if="(data | customfilter:'type':'facebook').active">
Your div content goes over here
</div>
<br>
<br>Second div - Active : true
<div ng-if="(anotherdata | customfilter:'type':'facebook').active">
Second div rendered
</div>
</div>
</body>

AngularJs Ui-Grid cannot show the Data and external filter with buttons and functions is not working with Complex JSON

Ui-Grid external filtering is not working and also didn't show me the data of an object Json. I am retreiving a data from server and it has complexity.
HTML--->
<div ng-controller="MainCtrl">
<input ng-model='filterValue'/>
<button ng-click='filter()'>Filter</button>
<button type="button" class="btn btn-sm btn-default"
ng-click="changeFilter('')">Filter Clear</button>
<button type="button" class="btn btn-sm btn-default"
ng-click="changeFilter('1')">Filter (1)</button>
<button type="button" class="btn btn-sm btn-default"
ng-click="changeFilter('5')">Filter (5)</button>
<button type="button" class="btn btn-success"
ng-disabled="!gridApi.grid.options.multiSelect"
ng-click="selectAll()">Select All</button>
<button type="button" class="btn btn-success"
ng-click="clearAll()">Clear All</button>
<br />
<div ui-grid="gridOptions" ui-grid-selection="" class="grid"></div>
<hr />
</div>
AngularJS---->
var app = angular.module('app', [
'ngTouch', 'ui.grid', 'ui.grid.selection']);
app.controller('MainCtrl', [
'$scope', '$http', '$log', '$timeout', 'uiGridConstants',
function ($scope, $http, $log, $timeout, uiGridConstants) {
$scope.gridOptions = {
enableFullRowSelection: true,
modifierKeysToMultiSelect: true,
enableRowSelection: true,
enableSelectAll: true,
showGridFooter:true,
enableFiltering: true
};
$scope.gridOptions.columnDefs = [
{ name: 'id' },
{ name: 'title'},
{ name: 'createdDate' },
{ name: 'description' }
];
$scope.gridOptions.multiSelect = true;
$scope.filter = function() {
$scope.gridApi.grid.refresh();
};
$scope.singleFilter = function( renderableRows ){
var matcher = new RegExp($scope.filterValue);
renderableRows.forEach( function( row ) {
var match = false;
[
'id',
'title',
'createdDate',
'description',
].forEach(function( field ){
if (row.entity[field].match(matcher)) {
match = true;
}
});
if (!match) {
row.visible = false;
}
});
return renderableRows;
};
$http.get('test.json')
.success(function(data) {
console.log(data);
$scope.gridOptions.data = data;
$timeout(function() {
if($scope.gridApi.selection.selectRow){
$scope.gridApi.selection.selectRow($scope.gridOptions.data[0]);
}
});
});
$scope.info = {};
$scope.selectAll = function() {
$scope.gridApi.selection.selectAllRows();
};
$scope.clearAll = function() {
$scope.gridApi.selection.clearSelectedRows();
};
$scope.changeFilter = function(val){
$scope.filterValue = val;
$scope.gridApi.grid.refresh();
}
$scope.gridOptions.onRegisterApi =
function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
gridApi.selection.on.rowSelectionChanged($scope, function (row) {
});
$scope.gridApi.grid.registerRowsProcessor( $scope.singleFilter, 200 );
gridApi.selection.on.rowSelectionChangedBatch($scope,function(rows){
var msg = 'rows changed ' + rows.length;
$log.log(msg);
});
};
}])
Server Response and simplified version of complexity--->;
[ {
"id": 1882,
"eventTypeId": 1,
"occuredDate": "2016-06-06T00:00:00",
"title": "Event Refresh",
"description": "Test for auto refresh",
"studyId": 2,
"statusId": 1,
"severityId": 3,
"priorityId": 2,
"status": 1,
"createdDate": "2016-06-06T13:53:42",
"$$hashKey": "uiGrid-0014"
},
{
"id": 1879,
"eventTypeId": 2,
"occuredDate": "2016-06-03T00:00:00",
"title": "Test one more timeout",
"description": "testing timeout",
"studyId": 4,
"statusId": 5,
"severityId": 2,
"priorityId": 2,
"status": 1,
"createdDate": "2016-06-06T13:53:42",
"$$hashKey": "uiGrid-001A"
},
{
"id": 1882,
"eventTypeId": 1,
"occuredDate": "2016-06-06T00:00:00",
"title": "Event Refresh",
"description": "Test for auto refresh",
"studyId": 2,
"statusId": 1,
"severityId": 3,
"priorityId": 2,
"status": 1,
"createdDate": "2016-06-06T13:53:42",
"$$hashKey": "uiGrid-0014"
}]
Here is an object i can reach any data of the server response but when the time has come to show data on ui-grid its kind of ignoring the whole data like as in the plunker that i created.
here is the not working plunker i have created one. Please have a look at that what I am missing here? and please update the plunk if any solution has come.
thanks
The code row.entity[field].match(matcher) is problematic as there is no match function, you need to use .test:
$scope.singleFilter = function( renderableRows ){
var matcher = new RegExp($scope.filterValue);
renderableRows.forEach( function( row ) {
var match = false;
['id','title','createdDate','description',].forEach(function( field ){
if (matcher.test(row.entity[field])) {
match = true;
}
});
if (match) {
row.visible = true;
}
else{
row.visible = false;
}
});
return renderableRows;
};
It's worth noting that your filter is in fact case-sensitive so if you search for 'event' you won't get anything, but 'Event' will get you three results.
Working plnkr

html is not compile on append new child in angular js

I am trying to insert a node dynamically, but the appended html is not getting compiled correctly.
This is the code on Fiddle.
<body ng-app="app">
<div ng-controller="appController">
{{tittle}}
<div name="name" ng-repeat="d in data" ng-click="click(d.id)" id="div{{d.id}}">{{d.id}} click me</div>
</div>
(function () {
var app = angular.module('app', []);
app.controller('appController', function ($scope, $compile) {
$scope.tittle = "test";
$scope.data = [{ id: 1, child: [{name:'renjith'}] }, { id: 3 }, { id: 4 }, { id: 5 }, { id: 6 }];
$scope.click = function (data, $element) {
debugger;
var scope = { id: "12" };
angular.element(document.querySelector("#div" + data)).append($compile("<div ngTransclude>{{d.id}}</div>")($scope.data));
}
});
})();

Categories