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);
}
Related
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'
i am trying to change and apply the value of an object in an angular js service.
i have been able to successfully watch the object and i saw the changes but i cannot apply it to take effect .
i am changing the value from my login controller .
i am watching the $rootScope.userobject and would want to apply changes immediately to $rootScope.userobj as it used in my service for some important stuff but it doesn't seem to apply . what am i doing wrong . see my code below
MyApp.angular.factory('appService', function ($rootScope, $timeout) {
$rootScope.userobject = localStorage.getItem('userdataconfig');
$rootScope.userobj = JSON.parse($rootScope.userobject);
if(!rootScope.userobj){
$rootScope.userobj = {};
}
$rootScope.$watchCollection('userobject', function(newvalue, oldvalue)
{
$timeout(function(){
$rootScope.userobject = newvalue;
$rootScope.userobj = JSON.parse($rootScope.userobject);// i need this updated value to take effect so i can use it in my userconfig below
});
}, true);
return {
userconfig: {token: $rootScope.userobj.token, id: $rootScope.userobj.id, username: "josieboy", fullname: $rootScope.userobj.name, profile_pix: ""}
}
})
MyApp.angular.controller('loginctrl', ['appService', '$scope', '$http', 'InitService', '$rootScope', function (appService, $scope, $http, InitService, $rootScope) {
$scope.loginnow = function()
{
var userdata = { 'id': 3, 'token':'867eb6fcd04b543f97ff6d2c0a64c557', 'name':'Ajose Joshua', 'profile_pix':''};
localStorage.setItem('userdataconfig', JSON.stringify(userdata));
var userobject = localStorage.getItem('userdataconfig');
$rootScope.userobject = userdata;
}
}])
I'm able to pass a router parameter when clicking a link to our 'count' page
$state.go('count', {targetName: object.name})
Because of what is established in the router as seen below:
url: '/count/:targetName',
We are using the data: option within UI-Router in combination with $state to dynamically set our page titles
<title ng-bind="'Application Name : ' + $state.current.data.pageTitle"></title>
I would like the pageTitle to include the :targetName. So in order to do that I believe i need to set a function in the data: property of the router. I've tried something like this:
data: {
pageTitle: function () {
getTargetName.$inject('$stateParams');
function getTargetName ($stateParams) {
return $stateParams.targetName;
}
}
}
This doesn't allow the page to resolve at all.
Any tips?
There is a working plunker
Let's have these kinds of states
// this is just a state, with its own pageTitle STRING
.state('home', {
...
data: {
pageTitle: "Just a home page"
},
})
// this is a parent state, with URL parameter 'someParam'
// nad pageTitle as a function
.state('parent', {
...
url: "/parent?someParam",
data: {
pageTitle: function ($stateParams) {
return `title with a param ${$stateParams.someParam}`;
}
}
})
// and to show that child can change it
.state('parent.child', {
...
data: {
pageTitle: "just a child title",
}
})
to make this line of code working:
<title>The tile is: {{ getTitle() }} </title>
we can just add small evaluation into $rootScope, but of course, it should be some service... take it as a simplified how to:
.run(['$rootScope', '$state', '$stateParams',
function ($rootScope, $state, $stateParams) {
$rootScope.getTitle = function(){
var state = $state.current;
var params = $stateParams;
if (state.data
&& state.data.pageTitle) {
if(typeof (state.data.pageTitle) === "function" ){
return state.data.pageTitle(params);
}
return state.data.pageTitle
}
return "no title for this state"
}
}])
and all these links will have different title
<a href="#/home">
<a ui-sref="parent({someParam: 1})">
<a ui-sref="parent({someParam: 'someValue'})">
<a ui-sref="parent.child">
Check it in action here
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 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.