Match the routeParam with the ID property and display the relevant object - javascript

I have a JSON file that looks like this:
[
{
"id":"112",
"title":"Title here",
"date":"1234567890"
}
{
"id":"113",
"title":"Title here",
"date":"1234567890"
}
...
]
I have two partials/views. A list view which lists all of the objects, and a detail page which is triggered by an "ng-click" which takes as a parameter the "id" property.
I have my routes working, and a detail partial.
I built a service to performe the request, and two controllers:
var chatServices = angular.module('itemServices', ['ngResource']);
chatServices.factory('Item',['$resource',
function($resource){
return $resource('data.json', {}, {
query: {method:'GET', params:{}, isArray:true}
});
}
]);
chatListApp.controller('ItemsController', ['$scope', 'Item', "$location",
function ($scope, Item, $location) {
$scope.items = Item.query();
$scope.detailPage = function (hash) {
$location.path(hash);
}
}]);
chatListApp.controller('DetailController', ['$scope', '$routeParams', 'Item',
function($scope, $routeParams, Item) {
$scope.data = Item.query();
$scope.itemID = $routeParams.itemID;
}
]);
So, I have a url like http://domain.foo/112, and I want it to show the first object of my JSON file (or the data array, if you prefer).
When I try {{data[0]}} in my view, I get the object, so how do I go about adding some logic and fetching the object with ID value equal to $scope.itemID (as in the routeParams?

You have the id, and you have the data, so you can loop over the data the get the item:
chatListApp.controller('DetailController', ['$scope', '$routeParams', 'Item',
function($scope, $routeParams, Item) {
$scope.itemID = $routeParams.itemID;
$scope.data = Item.query(function() {
for (var i = 0; i < $scope.data.length; i++) {
if ($scope.data[i].id === $scope.itemID) {
$scope.item = $scope.data[i];
break;
}
}
});
}
]);
then use item in your view.
Update: Use angular.forEach to replace for loop like this:
angular.forEach($scope.data, function(item) {
if (item.id === $scope.itemID) {
$scope.item = item;
}
});

Related

Pass data between functions in same controller using another service to get data

I get some data through Myservice from another Controller. I can see {{users.data}} from the view, but users.length = 0 ,and $data is empty, that means I can't access to the content of MyService in getData function.. if i replace MyService with json data like
$scope.users=[{..},{..}] it works fine
thank you ..
app.service('MyService', function() {
return data = [];
});
app.controller('tableController', function ($scope,
$filter,NgTableParams,MyService) {
$scope.users= MyService
$scope.usersTable = new NgTableParams({
page: 1,
count: 6
}, {
getData: function(params) {
params.total($scope.users.length);
$scope.da = params.sorting() ? $filter('orderBy')
($scope.users, params.orderBy()) : $scope.da;
$scope.da= params.filter() ? $filter('filter')
($scope.da, params.filter()) : $scope.users;
return $scope.da.slice((params.page() - 1) *
params.count(), params.page() * params.count());
}
}
);
});
When you get your data in the first controller you call MyService.setData(data); The service will store in its local var data and keep it there. Then in the second controller you can retrieve that data by calling MyService.getData()
app.service('MyService', function() {
var ret = {
data: [],
setData: function(inData) {
ret.data = inData;
},
getData: function() {
return ret.data;
}
};
return ret;
});
the first controller 1
app.controller('EventCtrl', ['$scope', 'EventService', 'MyService',
function ($scope, EventService , MyService) {
var baseUrl = '';
$scope.getEvents=function()
{
var apiRoute = 'http://localhost:9811/notification/notification/';
var _Event = EventService.getAll(apiRoute);
_Event.then(function (response) {
$scope.events= response.data;
MyService.data = $scope.events;
MyService.setData($scope.events);
$scope.VarCtrl1= MyService;
},
function (error) {
console.log("Error: " + error);
});
}
$scope.getEvents()
}]);
i updated the service but it doesnt work ..so i modified the first controller like this what do you think?
app.controller('EventCtrl', ['$scope', 'EventService', 'MyService',
function ($scope, EventService , MyService) {
var baseUrl = '';
$scope.getEvents=function()
{
var apiRoute =
'http://localhost:9811/notification/notification/';
var _Event = EventService.getAll(apiRoute);
_Event.then(function (response) {
var data = response.data
MyService.setData(data);
$scope.VarCtrl1= MyService;
},
function (error) {
console.log("Error: " + error);
});
}
$scope.getEvents()
}]);
Thanks for the update of the service now its better ...i can have data in $users and $data in tableController but orderBy need an array but i get this :( when i do consoleLoge($scope.users)
Object {data: Array(0), setData: function, getData: function}data:
Array(9)0: Object1: Object2: Object3: Object4: Object5: Object6:
Object7: Object8: Objectlength: 9__proto__: Array(0)getData:
function ()setData: function (inData)proto: Object
tableController.js:24

AngularJS factory for sharing data between controllers

I have an AngularJS application (1.4.10) and I need to share some data between two controllers.
So I made my factory:
.factory('CardsForService', function($http, URL){
var service = {
"block_id": '',
"service_id": ''
};
service.save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
service.get_data = function(){
return service;
};
return service;
})
I insert the data in the first controller:
$scope.open = function(id, type){
console.log(id +" "+type);
CardsForService.save_data(id, type);
...
And I try to get the data in another controller, like this:
$scope.$on('$routeChangeSuccess', function() {
if (algo_to_used == "service"){
var data = CardsForService.get_data();
console.log(data);
} else {
}
});
The console.log output this:
Object {block_id: "", service_id: ""}
If I try the same get_data() function in the same controller where I call the save_data() function I have the correct results.
What am I missing?
Change Factory Like this
app.factory('CardsForService', function(){
var service = {
"block_id": '',
"service_id": ''
};
var save_data = function(block_id, service_id){
service.block_id = block_id;
service.service_id = service_id;
};
var get_data = function(){
return service;
};
return{
saveData:save_data,
getData:get_data
}});
And in controllers
app.controller('FirstCtrl',function(CardsForService){
CardsForService.setData(id, type);
});
app.controller('SecondCtrl', function($scope, CardsForService){
$scope.data = CardsForService.getData();
});
This sounds like it could be a timing issue. Data from a service like this isn't reactive. Here's a snippet that should help visualize it.
var app = angular.module("demo", []);
app.factory("MySvc", function() {
var data = {};
data.setData = function(key, value) {
this[key] = value;
}
data.getData = function(key, def) {
return key in this ? this[key] : def;
};
return data;
});
app.controller("test1", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(100).then(function() {
MySvc.setData("foo", "bar");
$scope.data = MySvc.getData("foo");
});
}
]);
app.controller("test2", ["$scope", "MySvc", "$timeout",
function($scope, MySvc, $timeout) {
$timeout(500).then(function() {
$scope.data = MySvc.getData("foo", "baz");
});
}
]);
app.controller("test3", ["$scope", "MySvc",
function($scope, MySvc) {
$scope.data = MySvc.getData("foo", "asdf");
}
]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js "></script>
<div ng-app="demo">
<pre ng-controller="test1">Test 1: {{ data }}</pre>
<pre ng-controller="test2">Test 2: {{ data }}</pre>
<pre ng-controller="test3">Test 3: {{ data }}</pre>
</div>
Ok I solved the problem. Basically before I was using this code for the redirect to the new page:
$window.location.assign('/cards/service');
And now I switched to this code:
$location.path('/cards/service');
And it's working.
The only thing is that when it wasn't working when I redirect the page the console in the chrome inspector refresh for every reloading, now the console do not refresh. Can someone tell me the difference between those two functions?

AngularJS set var: http get

I have an angular filter set up which works great:
categorieFilter = angular.module("categorieFilter", [])
categorieFilter.controller("catFilter", ["$scope", "store", function($scope, store){
$scope.search = "";
$scope.products = [];
$scope.categories = [];
$scope.categories = store.getCategories();
$scope.products = store.getProducts();
$scope.filterProductsByCats = function(category){
$scope.search = category;
};
}])
categorieFilter.factory('store', function(){
var categories = ['Lattes','CC Blend','Frappes'];
var products = [
{name: 'Latte machiatto',category: 'Lattes'},
{name: 'Frappe ice',category: 'Frappes'},
{name: 'Latte caramel',category: 'Lattes'},
{name: 'Frappe speculoos',category: 'Frappes'},
{name: 'Cappucino',category: 'CC Blend'},
{name: 'Filter coffee',category: 'CC Blend'},
];
return {
getCategories : function(){
return categories;
},
getProducts : function(){
return products;
}
};
});
But the var categories and var products are still hard coded so I want to retreive the needed data from my server to fill these variables. And I can't seem to get this right? I have another function where I can get the required data but I don't know how I can get these 2 in 1...?
categories = angular.module('categories', []);
categories.controller("category",function($scope, $http){
var serviceBase = 'api/';
$http.get(serviceBase + 'categories').then(function (results) {
$scope.categories = results.data;
for(var i = 0; i < $scope.categories.length; i++){
var categories = $scope.categories[i];
}
});
});
So how can I properly set the var categories to the required $http.get to retreive my server data into the filter above?
I think you should be able to get rid of the hard coded block in the service and just return:
return {
getCategories: $http.get('/categories').success(function (data) {
return data;
}),
getProducts: $http.get('/products').success(function (data) {
return data;
})
}
Make sure you dependencies are setup correctly for the service though (i.e. $http):
.factory('store', function ($http) {
// The above return block here
});
And this should do the trick!

Using more than one resolve in states.js

I have a route as below:
var entryShow = {
name: 'entry.show',
url: '/:entry_id',
views: {
'#':{
templateUrl: TEMPLATES.entry_show,
controller : 'EntryShowController',
resolve: {
entryData: ['$stateParams', 'Entry', function($stateParams, Entry){
return Entry.getEntry($stateParams.entry_id);
}],
entryHistory: ['$stateParams','Entry',function($stateParams,Entry){
return Entry.getHistory($stateParams.entry_id);
}]
}
}
}
};
In my controller I have added the two resolves as follows :
App.controller('EntryShowController',['$scope','$state','entryData', 'Entry',
function($scope, $state, entryData, entryHistory, Entry) {
...
$scope.entry = entryData.data.entry;
console.log('Entry History');
console.log(entryData);
console.log(entryHistory);
$scope.entry.history = entryHistory.data;
...
}]);
Here in console.log I get the correct result for entryData but for entryHistory I get the entryService object instead of the result. Also when I swapped the getEntry and getHistoyr making getHistory being called in first resolve then the value in entryHistory was correct but in entryData I got the entryService object.
I have also checked the wiki for using resolves in state.js. What am I doing wrong ?
Following is my entryService:
App.factory('Entry', ['$http','Common', function($http,Common){
var entryService = {};
entryService.getEntry = function(entry_id) {
show_page_loader();
return $http.get(URLS.entry_show_path, {params: { id: entry_id }})
.success(function(result){
return result;
})
.error(function(data){
common_flash_error_message();
});
};
...
entryService.getHistory = function(entry_id){
return $http.get(
URLS.entry_history_path,
{
params: {id: entry_id}
}
)
.success(function(data){
return data;
})
.error(function(data){
common_flash_error_message();
});
};
return entryService;
}]);
You've forgot to inject entryHistory into the array so you've mixup your injections:
App.controller('EntryShowController',[
'$scope', '$state', 'entryData', 'Entry',
function( $scope, $state, entryData, entryHistory, Entry) {
}]);
Here, enterHistory will hold entry,

angularjs ng-repeat not updating view when new data comes in

I have a service which will make a call to the server and returns the data. I am binding service to a variable on scope.
Example:
Let the service be DataModelService
in the controller : $scope.data = DataModelService
in the view <div ng-repeat="value in data.persons">{{value.name}}</div>
My Code :
This is how my code looks like:
/**DataModelService**/
factory('DataModelService', [
'DataService',
function (DataService) {
var service;
service = {
changeState: function (params) {
DataService.changePersonState(params)
.then(function (response) {
service.loadData(response.data);
});
},
loadData: function (responseData) {
service.persons = responseData.persons;
}
}
return service;
}
]);
/**DataService**/
factory('DataService', ['$http',
function ($http) {
return {
changePersonState: function (params) {
return $http.post("url", params);
}
}
}
]);
/**DataController**/
.controller('DataController', ['DataModelService',
function (DataModelService) {
$scope.data = DataModelService;
}
]);
/view/
<div ng-repeat = "person in data.persons" >{{person.name}} </div>
On the view I am doing a ng-repeat on a key in data i.e. ng-repeat="value in data.persons"
and also I have an option to change the state of person to active or inactive, so whenver i make a change to the state of the person, a call is sent to the server and data is set into the Service and as it is binded to the view, it should automatically update the data. But whats happening in my case, ng-repeat is not removing old data and instead it is appending new data to the old data.
For me its not good approach to write promise callback (then) into service. Because in your case, DataModelService returns data with some delay but not promise. And we don't know when.
So the way to make it work to add basic $timeout and fetch data from service by using other method.
So my suggestion is Demo
and your fixed example: Demo2
If we will take your example, it should be like:
JS
var fessmodule = angular.module('myModule', ['ngResource']);
fessmodule.controller('fessCntrl', function ($scope, DataModelService, $timeout) {
$scope.alertSwap = function () {
DataModelService.changeState('ff');
$timeout(function(){
$scope.data = DataModelService.getResponse();
}, 10);
}
});
fessmodule.$inject = ['$scope', 'Data', '$timeout'];
/**DataModelService**/
fessmodule.factory('DataModelService', [ 'DataService',function (DataService) {
var value = [];
var service = {
changeState: function (params) {
DataService.changePersonState(params)
.then(function (response) {
value = response.persons;
});
},
getResponse : function(){
return value;
}
}
return service;
}
]);
/**DataService**/
fessmodule.factory('DataService', ['$q',function ($q) {
var data = { // dummy
persons: [{
name: "Bob"
}, {
name: "Mark"
}, {
name: "Kelly"
}]
};
var factory = {
changePersonState: function (selectedSubject) {
var deferred = $q.defer();
deferred.resolve(data);
return deferred.promise;
}
}
return factory;
} //function
]);

Categories