I have an array with JSON objects in my $scope.users which is working correctly. I'm now trying to set up a "detail" page for an individual user by filtering the users list to get a single user.
I've been close for an excruciating amount of time, and for some reason I can't find documentation or any examples of how to do what I'm doing. Maybe this isn't the correct way to do this in Angular and/or maybe I'm not searching for the right thing?
I've tried getting the object based on userId from the list in the controller, and I've tried passing a resolve in the state, but I didn't get either method to work. What is the best way to go about getting the single user with id of $stateparams.userId?
Everything else is working correctly (i.e. all the routing, getting the users on #/users).
// routing section of app.js
// Routing
$urlRouterProvider.otherwise('/');
$stateProvider
.state('home', {
url: '/',
templateUrl: 'static/partials/main/home.html'
})
.state('users', {
url: '/users',
templateUrl: 'static/partials/accounts/users.html',
controller: 'UserController'
})
.state('profile', {
url: '/users/{userId}',
templateUrl: 'static/partials/accounts/profile.html',
controller: 'UserController'
});
// controller.js
var rlGlobalControllers = angular.module('rlGlobalApp.controllers', []);
rlGlobalControllers.controller('UserController', function($scope, $stateParams, $filter) {
var userId = $stateParams.userId;
$scope.users = [
{
'id': 1,
'name': 'Shadrack'
},
{
'id': 2,
'name': 'JP'
},
{
'id': 3,
'name': 'Adam'
}
];
// $scope.user = ???
});
# profile.html
<div ng-include src="'/static/partials/shared/header.html'"></div>
<div class="container">
<div class="row">
<p>users data: {{ users }}</p>
<p>user data: {{ user }}</p>
</div>
</div>
User Array.prototype.filter method to find objects satisfying criteria:
$scope.user = $scope.users.filter(function(user) {
return user.id === userId;
})[0];
This is the most natural way to solve it. If however your users array is very large (like millions, for example (hope it's not)) then for-loop-break solution of juunas is preffered as more effective.
You could just do this in the controller:
for(var i = 0; i < $scope.users.length; i++){
if($scope.users[i].id === userId){
$scope.user = $scope.users[i];
break;
}
}
var output = [],
keys = [];
Array_Value.forEach(function (item) {
var key = item["Field name"];
if (keys.indexOf(key) === -1) {
keys.push(key);
output.push(item);
}
});
this.Title = output;
Instead of Array_value and field name, give your data.
Related
This is the part of my HTML:
<td>
<button class="btn btn-primary" ui-sref="edit({id: v.customerId})" ui-sref-opts="{reload: true}">Edit</button>
<button class="btn btn-primary" ng-click="removeRow(v.firstName);">Delete</button>
</td>
as you can see I am passing the customerId as and id to be one of the parameters displayed in the url
app.js:
var app = angular.module('webtrekkApp', ['ngSanitize', 'ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('edit', {
name: 'edit',
url: '/users/:id/edit',
templateUrl: './views/customer-details.html',
controller: 'ctrl',
params: {
obj: null
}
});
});
ctrl.js:
//If 'initData' isn't set, then set it up by default
if(!localStorage.getItem('initData')) {
$window.localStorage.setItem('initData', JSON.stringify($scope.initData));
}
$scope.retrievedData = JSON.parse($window.localStorage.getItem('initData'));
for (var i = 0; i < $scope.retrievedData.length; i++) {
$scope.retrievedData[i].birthdayDate = new Date().getFullYear() - new Date($scope.retrievedData[i].birthdayDate).getFullYear();
}
$scope.sortedType = 'firstName';
$scope.sortedReverse = false;
//Remove Rows and Update localStorage Key Values
$scope.removeRow = function(name) {
var index = $scope.retrievedData.findIndex(function(obj) {return obj.firstName === name});
$scope.retrievedData.splice(index, 1);
window.localStorage.setItem('initData', JSON.stringify($scope.retrievedData));
};
$state.go('edit', {obj: $scope.retrievedData});
So I a table, and when users clicks on 'edit', I need THAT object to be passed to the ui.router so I can display it in customer-details.html. How can I do it? I am doing something wrong here. I have read all the documentation on ui.router but do not know should $state.go be defined in the initial controller or in some other. Also I've followed this question, but couldn't get it to work: How to pass custom data in $state.go() in angular-ui-router?
In your edit state you have two parameters, id and obj, one of which inside the url.
But when you trigger the state from your controller you are not passing the id parameter and you did not define a default value
$state.go('edit', {obj: $scope.retrievedData});
try adding it inside your params object
params: {
obj: null,
id: null
}
EDIT:
to answer your further question:
<button class="btn btn-primary" ng-click="handleItem(v);">Go to Edit state</button>
$scope.handleItem = function(item){
//here extract your item specific data from $scope.retrievedData then change the state
var itemData = getItemData(item, $scope.retrieveData);
$state.go('edit', {obj: itemData});
}
Hi you are not using controller, if you want to pass parameters to $state.go() you should have controller to get that value in particular state.
app.js
var app = angular.module('webtrekkApp', ['ngSanitize', 'ui.router']);
app.config(function ($stateProvider, $urlRouterProvider) {
$stateProvider
.state('edit', {
name: 'edit',
url: '/users/:id/edit',
templateUrl: './views/customer-details.html',
controller: 'myController',
params: {
obj: null
}
});
});
in Controller
function myController($state) {
conrole.log($state.params.obj);
}
I'm new to Ionic. I write code for list. List is working perfectly but when click on any list-item it's not showing any data.
It showing me this error "Cannot GET /pilliondetails/1" how can i solve this?
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
console.log(savedData);
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
})
PillionList Controller:
.controller('PillionListCtrl',function($scope,$ionicHistory,myService){
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
$scope.pillions = [];
var promise=myService.get();
$scope.pillions=myService.get();
})
PillionDetail Controller:
.controller('PillionDetailCtrl',function($scope, $ionicHistory, $stateParams, myService)
{
$scope.myGoBack = function() {
$ionicHistory.goBack();
};
var promise=myService.get($stateParams.requestId);
console.log(promise);
})
PillionList.html :Showing list pf Pillions
<ion-list>
<ion-item data-ng-repeat="pillion in pillions">
<div class="list list-inset">
{{pillion.request_departure_date}}-{{pillion.request_departure_time}}
{{pillion.request_from}} >> {{pillion.request_to}}
{{pillion.user_first_name}} {{pillion.user_last_name}}
<a ui-sref="pilliondetails({pillionId:pillion.request_id})" nav-direction="enter">
<h2>More Details...</h2>
</a>
</div>
</ion-item>
</ion-list>
my app.js
.state('pillionlist', {
url: '/pillionlist',
templateUrl: 'templates/pillionlist.html',
controller: 'PillionListCtrl'
})
.state('pilliondetails', {
url: '/pillionlist/:pillionId',
templateUrl: 'templates/pilliondetails.html',
controller: 'PillionDetailCtrl'
})
Its redirecting to pillionDetail view but not showing data.
Please help.
The first thing i noticed is
ui-sref="pilliondetails({pillion.request_id})"
it should be key-value pair like this
ui-sref="pilliondetails({ your_id : pillion.request_id})"
and in stateProvider, the url of details page should contain parameter. for eg.
url : '/pilliondetails/:your_id'
In this ionic application I want to enter data from the search page and show the results in the next page. But when i try it it wont work. And i can get the search results to the console. and the data wont pass to the next page even i make the same controller for both the pages. Please help me to resolve this issue!! Thanks!!
This is my button code ('searchA' is the object containing entered data)
<button type="button" class="button button-block button-positive" ng-click="search(searchA)" ui-sref="app.MainSearchResult">Search</button>
These are my states (app.js file)
.state('app.MainSearch', {
cache:false,
url: '/MainSearch',
views: {
'menuContent': {
templateUrl: 'templates/MainSearch.html',
controller: 'MainSearchCtrl'
}
}
})
.state('app.MainSearchResult', {
url: '/MainSearchResult,
views: {
'menuContent': {
templateUrl: 'templates/MainSearchResult.html',
controller: 'MainSearchResultCtrl'
}
}
})
This is my search function (controller.js)
$scope.search = function(searchA){
console.log('No : '+ searchA.emp_EPF);
console.log('Name : '+ searchA.emp_Name);
console.log('Company :'+ searchA.emp_Comp);
//console.log('qualification Type : ' + emp_qualiType);
console.log('-------------------');
$http({
method: 'GET',
url: 'http://localhost/mas/Search.php',
params: {employeeNo : searchA.emp_EPF,
employeeName : searchA.emp_Name,
employeeCompany : searchA.emp_Comp,
employeeBusinessUnit : searchA.emp_BU,
employeeTeamName : searchA.emp_Team,
employeeSecondaryCompany : searchA.emp_secondmant,
employeeRelatedEmployee : searchA.emp_relatedEmp,
employeeWorkLevel : searchA.emp_workl,
employeeDesignationName : searchA.emp_designation,
qualificationType : searchA.emp_qualiType,
qualificationField : searchA.emp_qualiField,
programName : searchA.emp_progName,
serviceProvider : searchA.emp_svcProvider
}
}).then(function successCallback(response) {
$scope.searchResults = response.data['records'];
console.log('success :'+ JSON.stringify($scope.searchResults));
}, function errorCallback(response) {
console.log('error',response);
// called asynchronously if an error occurs
// or server returns response with an error status.
});
angular.copy($scope.resetData,searchA);
}
This is my results set view of the next page.
<ion-list ng-repeat="x in searchResults">
<ion-item class="item item-text-wrap" >
<div >
<h2>{{x.employeeNo}}</h2>
<p>{{x.employeeName}}</p>
<div>
<a class="button button-outline button-medium button-positive" >Edit</a>
</div>
</div>
</ion-item>
</ion-list>
Please Help me to get this done!!
Thanks!!
A simple solution is to have a factory return an object and let your controllers on both pages work with a reference to the same object
var myApp = angular.module('myApp', []);
myApp.factory('Data', function(){
//Make your search request here.
return Data;
});
myApp.controller('MainSearchCtrl', function( $scope, Data ){
$scope.searchResults = Data;
});
myApp.controller('MainSearchResultCtrl', function( $scope, Data ){
$scope.searchResults = Data;
});
The easiest way to share data between views/scopes/controllers, the easiest way is to store it in $rootScope.
In MainSearchCtrl,
$scope.searchResults = response.data['records'];
$rootscope.searchResults = $scope.searchResults;
You can use the same variable on the SearchResults page as well.
I want to implement 'edit' feature to any book, but I can't get my book.
How it works now:
I click on the any record (which is <tr>).
I am being redirected to the books_edit state
This 'edit' page must have all the data in form of current book (but it doesn't).
So, the question is: How can I pass book from the books state to books_edit state and submit it correctly?
HTML piece:
<tr ng-click="bookCtrl.editBook(book)" ng-repeat="book in bookCtrl.books">
<td>{{ book.name }}</td>
<td>{{ book.author }}</td>
<td>{{ book.price }}</td>
<td>{{ book.pubdate | date }}</td>
<td>{{ book.coverUrl }}</td>
<td>{{ book.pagesCount}}</td>
</tr>
States:
.state('books_new', {
url: '/books/new',
templateUrl: 'books/book_new.html',
controller: 'BookCtrl as bookCtrl'
})
.state('books_edit', {
url: '/books/edit',
templateUrl: 'books/book_edit.html',
controller: 'BookCtrl as bookCtrl'
})
.state('books', {
url: '/books',
templateUrl: 'books/books.html',
controller: 'BookCtrl as bookCtrl'
})
Controller's methods:
editBook: function(book) {
if (book) {
console.log(book); // logs correct book
$state.go('books_edit'); // tried to send `book` as a parameter, didn't work
}
},
submitBook: function(book) {
if (book) {
console.log(book);
return books.$save(book).then(function(data) {
$state.go('books');
});
}
}
Edit snippet:
<form class="container col-lg-3" ng-submit="bookCtrl.submitBook(book)">
<div class="input-group">
<label class="col-sm-2 control-label">Назва:</label>
<input type="text" ng-model="book.name" class="form-control">
I've tried to send book as a parameter in state, but no result.
The best way to handle this, is to be 'stateless'. This way a user can bookmark the edit page, and reload the page without requiring any state to be present in the app.
Pass the id of the book you want to edit as a url parameter to the edit state, like so:
state config:
.state('books_edit', {
url: '/books/edit/:bookId',
templateUrl: 'books/book_edit.html',
controller: 'BookCtrl as bookCtrl'
})
controller:
$state.go('books_edit', {bookId: book.id});
In the edit controller, fetch the book using the id from the url, using the $stateParams service:
angular.module('myapp').controller('BookCtrl', function($scope, $stateParams){
//fetch the book id from the url params
var bookId = $stateParams.bookId;
//now get the book with the given id
});
I would advise to use a separate controller for the edit functionality, i.e. do not use 'BookCtrl' for every view.
Define state parameters as following
$stateProvider.state('books_edit', {url: '/books/:bookId',params: {obj: null},templateUrl: 'books/books_edit.html',controller: 'booksCtrl'})
when calling pass parameter like this:
$state.go('books_edit',{obj: myobj});
In controller you can receive parameter using
$state.params.obj
Hope it helps.
You can use a service to reach this. Create a service where you can set/get the value and inject in both controllers. The service looks like this:
app.service('bookService', function() {
var books = [];
var addBook = function(obj) {
books.push(newObj);
};
var getBook = function(){
return books;
};
return {
addBook: addBook,
getBook: getBook
};
});
And, in controller:
editBook: function(book) {
if (book) {
// ensure to inject productService in controller
bookService.addBook(book)
console.log(book); // logs correct book
$state.go('books_edit'); // tried to send `book` as a parameter, didn't work
}
},
In book_edit controller:
.....
// ensure to inject productService in controller
$scope.book = bookService.getBook(book)
....
You can also use $broadcast, read more:
On and broadcast in angular
Hope it helps
Try passing it in state.go as something like this "books/" and then use state params to retrieve it.
state('books_edit', {
url: '/books/edit:bookID',
templateUrl: 'books/book_edit.html',
controller: 'BookCtrl as bookCtrl'
})
submitBook: function(bookID) {
if (bookID) {
console.log(bookID);
return books.$save(bookID).then(function(data) {
$state.go('books/'+<bookID>);
});
}
}
in the Controller
editBook: function($scope, $stateParams) {
$scope.bookID = $stateParams.bookID;
}
Thanks #fikkatra and #Gurpinder for helping with this! The complete solution is following:
Add this to the books_edit state:
params: {data: null}
In the editBook() function send parameters to the next state:
$state.go('books_edit',{bookId: book.$id, data: book});
Add this to the bookCtrl - bookCtrl.currentBook = $state.params.data;
Change ng-model in the view to bookCtrl.currentBook.KEY_NAME
I am trying to return an object, taht I populate in a forEach loop, with angulars $scope from a controller, but when I try to loop it out with ng-repeat I get no result.
When i console.log the object I get the expected result
But when I try to return it with $scope and show it with ng-repeat I get no results what so ever.
Here is my controller
myAppControllers.controller('musicCtrl', ['$scope', '$http', function($scope, $http) {
var i = 0,
playlists = {};
// Get the playlists from soundcloud
$http({ method: 'GET', url: 'http://api.soundcloud.com/users/gimle-sound-tjek/playlists.json?client_id=c2dfe07de1d18d689516884ce22b7aae' }).
success(function(data) {
data.forEach(function() {
// Populate the object
playlists[i] = {
"title" : data[i].title,
"permalink": data[i].permalink,
"genre": data[i].genre
}
i++;
});
console.log(playlists);
$scope.playlists;
}).
error(function() {
$scope.playlists = '';
});
}]);
My ng-repeat looks like this
<div ng-repeat="playlist in playlists">
<h3>{{ playlist.title }}</h3>
...
I am expecting that is has something to do with the way I send the object back with $scope.playlists?
First of all maybe use push instead this i++ fun.
You push those playlist entries into the playlist variable outside the scope.
myAppControllers.controller('musicCtrl', ['$scope', '$http', function($scope, $http) {
$scope.playlists= [];
// Get the playlists from soundcloud
$http({ method: 'GET', url: 'http://api.soundcloud.com/users/gimle-sound-tjek/playlists.json?client_id=c2dfe07de1d18d689516884ce22b7aae' }).
success(function(data) {
data.forEach(function(entry) {
// Populate the object
$scope.playlists.push({
"title" : entry.title,
"permalink": entry.permalink,
"genre": entry.genre
});
//OR: $scope.playlists.push(entry);
});
}).
error(function() {
$scope.playlists = '';
});
}]);
What if you try $scope.playlists = [] instead of var playlist = {}