I load some data from the server, and then update the view using ng-repeat. The user has the ability to edit the data in another page. Now, is the part where I'm a bit confused. I can pass some parameters using $routeProvided combined with $routeParams, lets say id and fetch the data again from the server depending on that id. I believe there's a better way, something like passing the whole object to the next controller, rather than conducting another call the server. That's what I've got working right now:
app.config(function($routeProvider) {
$routeProvider
.when('/editPost/:postId/:author', {
templateUrl: 'editPost.html',
controller: 'editPostCtrl'
});
});
app.controller('editPostCtrl', function($scope, $routeParams) {
console.log($routeParams.author + ", " + $routeParams.postId);
});
Now, I cant extract the object with the following code:
HTML:
<div ng-repeat="post in posts">
<button class="btn" ng-click="editPost(post)">Edit</button>
</div>
JS:
app.config(function($routeProvider) {
$routeProvider
.when('/editPost/:post', {
templateUrl : 'editPost.html',
controller : 'editPostCtrl'
});
});
app.controller('editPostCtrl', function($scope, $routeParams) {
console.log($routeParams.post); //results in [object object]
});
Is there a better way for achieving this?
Related
I understand how two-way data binding works with AngularJS but I'm struggling to make it work in a situation described below. I've a index.template.html, home.template.html, search.template.html, app.js, search.controller.js and search.service.js files. I've a input form on a home page at '/' url.
<li ng-controller="searchCtrl"> //searchCtrl() in search.controller.js file
<form role="search">
<input type="text" ng-model="searchstring"
placeholder="Enter string here"> <br />
<button type="submit"
ng-click="searchString(searchstring)">Search</button>
</form>
</li>
And I've search.template.html to display the results as follows,
<html>
<body>
<h1> SearchedText</h1>
<h2> {{ searchedtext }} </h2>
</body>
</html>
search.controller.js is as follows,
(function () {
angular
.module('twowaybindapp')
.controller('searchCtrl', searchCtrl);
searchCtrl.$inject = ['$scope', 'SearchService'];
function searchCtrl($scope, SearchService) {
$scope.searchString = function(searchtext) {
SearchService
.getSearchResults(searchtext) //getSearchResults in search.service.js
.success(function(data) {
console.log('Service call is a success with result:');
console.log(data);
$scope.searchedtext = data;
}).error(function(e) {
console.log(e);
});
};
}
})();
My app.js file is as follows,
var myApp = angular.module('twowaybindapp', [ 'ngRoute' ]);
myApp.config(['$routeProvider', '$locationProvider',
function($routeProvider, $locationProvider) {
$routeProvider.
when('/', {
templateUrl: 'home.view.html'
}).
when('/search', {
templateUrl: 'search.view.html',
controller: 'searchCtrl'
}).
otherwise({ redirectTo: '/' });
}]);
With this background, When I've both form and results html text (content of search.template.html) in the same home.template.html, things work fine and I see all the results but if I put them in separate files as above, either I don't know how to open the results in new view after the call or don't know if data-binding is not working. I do see results in console.log() in both cases that mean service call is working okay as expected. This might be silly question but I really need help with this. Would it work if the search form is a part of navigation directive at the top of every page and results needs to be shown below in a main ng-view? Any help is appreciated. Thanks.
-- Atarangp
When you write {{smth}} in html it parsed to $scope.smth, each controller has its own scope object, by default scopes are nested:
<div ng-controller="c1" ng-init="smth = 1">
<div ng-controller="c2">
{{smth}} << 1
</div>
</div>
<div ng-controller="c3">
{{smth}} << undefined
</div>
When you defined several views - they will have different scopes, so you can not see one scope from another.
Fastest way to make it work is change to $rootScope.searchedtext = data; cause all your scopes nests from root scope.
Other way is to make common parent state and access and set your property there.
Yet another ways are: use your own service to store data, pass data using events, pass data using properties in state obj...
I am stuck in calling json text inside the ng-view. In normal HTML {{profile.experience}} this works perfect fine. fetching the data from json.
But since I have add the ng-view {{profile.experience}} is unable to fetch the data from json.
<div class="profile-snapshot">
<ul>
<li><span>Experience:</span><p> {{profile.experience}}</p></li>
<li><span>Education:</span><p> {{profile.education}}</p></li>
<li><span>Designation:</span><p>{{profile.designation}}</p></li>
<li><span>Age:</span><p>32</p></li>
<li><span>City:</span><p>Thane</p></li>
</ul>
</div>
This what my json look like
{
"experience": "Experience 8 Years asda s",
"education": "MBA, B.COM",
"designation": "UX Designer, Front End Developer"
}
this is what my angularjs code looks like
var accord = angular.module('accord', []);
var profileLoad = angular.module('profileLoad',[]);
var app2 = angular.module('main-app', ['accord','profileLoad','ngRoute']);
profileLoad.controller('profileCntrl', function($scope, $http){
'use strict';
$http.get('candidateProfile.json').success(function(data) {
$scope.profile = data;
});
});
app2.config(function($routeProvider) {
$routeProvider
.when('/home', {
templateUrl: 'profile.html',
controller: 'StudentController'
})
.when('/viewStudents', {
templateUrl: 'profile-edit.html',
controller: 'StudentController'
})
.otherwise({
redirectTo: '/home'
});
});
can anyone please help me in fetching the json data inside ng-view?
Unless I'm missing something, I think
profileLoad.controller('profileCntrl', function($scope, $http){ ... }
should be
profileLoad.controller('StudentController', function($scope, $http){ ... }
You're retrieving the data in a controller that's not mapped to a template in $routeProvider.
Also, you should put your $http.get in a service and inject that service into your controller. Keep your concerns separated and your controllers lean.
Since I was already applying the controller. Only thing I needed to do is remove the controller: 'StudentController'.
That solved the problem for me.
I really appreciate the quick reply from the members here.
Cheers guys
The problem I'm having here is not being able to find the right question to ask.
I'd like to use a single partial and populate it with different data based on a url. The url would look something like this
localhost:8080/#/users/USER_ID
Where users directs to a user profile partial, and corresponding controller, and USER_ID would be sent in to an HTTP request to retrieve user data that would then populate the user profile partial.
Any direction in solving this is greatly appreciated.
If you are using ui-router which I highly recommend:
$stateProvider
.state('users', {
url:'/users/:userId',
templateUrl: 'user.html',
controller:'UserCtrl'
})
You can then access the userId in your controller:
App.controller('UserCtrl', ['$scope', '$stateParams', '$state', 'User', function($scope, $stateParams, $state, User) {
'use strict';
/* controller code */
var req = User.$find($stateParams.userId);
}]);
I am also using angular-rest-mod to make HTTP calls to an api when I do User.$find(id)
I found a solution that was a lot more straight forward than I had anticipated
app.js
$routeProvider.
when('/user/:id', {
templateUrl: 'user.html',
controller: 'userController'
});
Then in the implementation of userController, $routeParams can be used to retrieve the value of id from the url.
Okay so I would probably go like this. First I would recommend Ui-Router instead of ngRoute this allows you to create your states for example
$stateProvider
// setup an abstract state for the tabs directive
.state('A', {
params: [A,B,C,D,E],
url: "/A",
templateUrl: "templates/YourView.html",
controller: "YourController"
})
.state('B', {
params: [F,G,H,I,J],
url: "/B",
templateUrl: "templates/YourView.html",
controller: "YourController"
})
Basically this says when your Url is "/A" the "YourController" is used and the YourView.html is used so If I understood correct you have 1 view where you want to show different data depending on the Url.By Injecting 'ui.router'into your module and $state into your Controller you can access $state.current.params
Example Controller
.controller('ExampleController', ['$rootScope', '$scope', '$state', function ($rootScope, $scope, $state){
//Here you get your params
//This will return you either [A,B,C,D,E] or [F,G,H,I,J] depending if Url is /A or /B
$scope.showList = $state.current.params;
//Another Possibility with this is to listen for a StateChange
$scope.$on('$stateChangeSuccess', function (ev, to, toParams, from, fromParams) {
//Here you can access all Params from the state you just left to the state you are going
});
}]);
Now you can just show this in the YourView.html like this
<div ng-repeat="item in showList">
<p>{{item}}</p>
</div>
So If your at /A the list shows A,B,C,D,E and if you are on /B it shows F,G,H,I,J
I hope this was helpful
I have gotten a list of users from my sails back end into an angular view using $http. However, all I need is the information of the current user, and I need to access each attribute individually. Can someone provide for me an example of how I might go about this?
In api/controllers/UserController.js. This sails function returns the current user information in req.user.
module.exports = {
getUser: function(req,res) {
return res.send(req.user);
};
In config/routes.js. This is the route to the 'getUser' function in UserController.js.
'/getUser': {
controller: 'UserController',
action: 'getUser'
}
In assets/js/controllers.js, here is the $http request to the 'getUser' function in UserController.js. This is how you get the information from req.user into the front end.
angular.module('myApp.controllers', []).
controller('myCtrl', ['$scope', '$http', function($scope, $http) {
$http.get("http://localhost:1337/user/getUser").then(function(result) {
$scope.currentUser = result.data;
})
}]);
In assets/js/app.js, make sure your angular route is set to your view.
config(['$routeProvider', function($routeProvider) {
$routeProvider.when('/view', {templateUrl: 'partials/view.html', controller: 'myCtrl'});
}]);
After putting this code (with your own variables/routes/server info) in the correct places, you can access the current user in your view like this
<div ng-controller="myCtrl">
{{ currentUser.email }} <br>
{{ currentUser.username }} <br>
{{ currentUser.etc }}
</div>
I searched the internet high and low for a week for an answer on how to do this and eventually came up with this. I see that a lot of people (on this site especially) have asked the same question, and I never really found a good, explicit answer. So I thought I would post what I've come up with as an answer to my own question.
I have the following URL:
http://myUrl.com/#/chooseStyle?imgUpload=6_1405794123.jpg
I want to read the imgUpload value in the query string - I'm trying:
alert($location.search().imgUpload);
But nothing alerts, not even a blank alert - but console reads:
$location is not defined
I need this value to add into a controller to pull back data, and also to carry into the view itself as part of a ng-src
Is there anything I'm doing wrong? this is my app config:
capApp.config(function($locationProvider, $routeProvider) {
$locationProvider.html5Mode(false);
$routeProvider
// route for the home page
.when('/', {
templateUrl : '/views/home.html',
controller : 'mainController'
})
// route for the caption it page
.when('/capIt', {
templateUrl : '/views/capIt.html',
controller : 'mainController'
});
}):
This is the view:
<div class="container text-center">
<h1 class="whiteTextShadow text-center top70">Choose your photo</h1>
</div>
<script>
alert($location.search().imgUpload);
</script>
Main controller:
capApp.controller('mainController', function($scope) {
$scope.message = 'Whoop it works!';
});
My end goal is that I can find a solution to capturing and re-using data from the query string.
I will also mention, this is only my first week in Angular, loving it so far! A lot to learn...
<script>
alert($location.search().imgUpload);
</script>
You're making two mistakes here:
executing code while the page is loading, and the angular application is thus not started yet
assuming $location is a global variable. It's not. It's an angular service that must be injected into your controller (or any other angular component). This should cause an exception to be thrown and displayed in your console. Leave your console open always, and don't ignore exception being thrown.
You should not do this
<script>
alert($location.search().imgUpload);
</script>
// you need to inject the module $location
//(either in service, or controller or wherever you want to use it)
// if you want to use their APIs
capApp.controller('mainController', function($scope, $location) {
$scope.message = 'Whoop it works!';
//use API of $location
alert($location.search().imgUpload);
});