get values to edit in an other page with Angular - angularjs

I have values that I want to edit in an other page
<tr ng-repeat="facilitator in listFacilitators" ng-click="showDetails(facilitator);goToFacilitatorP()">
<td>{{facilitator.username}}</td>
<td><li><ul>{{facilitator.cwsessionsAnime}}</ul></li></td>
<td><li><ul>{{facilitator.profilFollow}}</ul></li></td>
</tr>
when I click on I'm supposing to be redirected in another page to show the details and edit them , so I tried to do this in the controller:
$scope.showDetails= function(facilitator){
$scope.selectedFac= facilitator;
}
and in the second page, I do this:
<tr>
<td> {{selectedFac.username}}</td>
<td> {{selectedFac.lastname}}</td>
<td> {{selectedFac.firstname}}</td>
<td> {{selectedFac.title}}</td>
</tr>
it works in the same page but not when I'm redirected, can you help me please?
UPDATE:
I do this but I still haven't data in the seconde page:
1- In the first controller for the 1 page I declared:
profilCtrl.controller('ProfilCtrl', [ '$scope','$location', 'profilService', 'facilitatorPService', function($scope,$location, profilService, facilitatorPService) {
/* ---- appel a facilitator Service ---- */
var facilitator = '';// What ever this is set to in the first place
facilitatorPService.facilitator = facilitator;
2- In my 2nd controller (for the second in where I want to show the details) , I have declared:
facilitatorPCtrl.controller('facilitatorPCtrl', [ '$scope','$rootScope','$cookieStore','$location','membreService','facilitatorPService','userService',function($scope,$rootScope,$cookieStore,$location, membreService,facilitatorPService, userService) {
facilitatorPservice.editFacil= function($scope){
$scope.showDetails = function(){
$scope.selectedFac = facilitatorPService.facilitator;
}
};
3- Ans in my service facilitatorPService I have this:
facilitatorPService.factory('facilitatorPService', [ '$resource','$http', function($resource,$http) {
var service = {
getAllFacilitators : function($scope){
return $resource('/gari-web/services/facilitators/AllFacilitators', {}, {
query : {
method : 'GET', isArray:true,
}}
});
},
editFacil: function($scope){
var self= this;
self.facilitator={};
}};
return service;
} ]);
4- in My html page I put this:
<td>{{selectedFac.username}}</td>
Can someone please tell me what I did wrong, I don't find the mistake

Controllers are 'flushed' when you change views. To keep data from a view to another, store your data within a Service.
UPDATE
.service('FacilitatorService', [
function() {
var self = this;
self.facilitator = {};
}
])
Then in your controllers, inject yourself the service you just created.
.controller('FirstController', ['FacilitatorService',
function(FacilitatorService) {
var facilitator = '';// What ever this is set to in the first place
FacilitatorService.facilitator = facilitator;
}
])
And in your second controller
.controller('SecondController', ['FacilitatorService', '$scope',
function(FacilitatorService, $scope) {
$scope.showDetails = function(){
$scope.selectedFac = FacilitatorService.facilitator;
}
}
])
Like this, your FacilitatorService.facilitator data will be accesible in all your controllers that use FacilitatorService

I recommend using ui router, this resolve two problems, the view change and the data share.
Read more about router ui
doc http://angular-ui.github.io/ui-router/site/#/api/ui.router
The current state
$stateProvider
.state('current', {
url: "/curent",
templateUrl: 'current.html',
controller: 'currentCtrl'
})
Then you can choose how change the view and share the data, the first is the controller, the second is html. Only use one
From current controller (option 1)
$scope.showDetails= function(facilitator){
$state.go('togo', {myCurrentdata: facilitator}) ;
}
From current html (option2)
<tr ng-repeat="facilitator in listFacilitators" ui-sref="togo({myCurrentdata : facilitator})">
<td>{{facilitator.username}}</td>
<td><li><ul>{{facilitator.cwsessionsAnime}}</ul></li></td>
<td><li><ul>{{facilitator.profilFollow}}</ul></li></td>
</tr>
The state that you want to go
$stateProvider
.state('togo', {
url: "/togo",
templateUrl: 'togo.html',
controller: 'togoCtrl'
param: {myCurrentdata: null}
})
To go controller
if($stateParams.myCurrentdata){
$scope.selectedFac = $stateParams.myCurrentdata
}

Related

How to show JSON data in HTML

I want to show the following JSON in an Angular page :
{"_id":"58b11","name":"Somename","city":"Paris","number":456789123,"__v":0}
I get this data by clicking on a link in an Angular page:
<td ng-click="getData(user._id)">
{{user.name}}
</td>
I am able to get the data from the db and show in the angular page in proper HTML. Now when I click on the link, i get the desired data in JSON on the page http://localhost:8080/api/students/58b11. I want to be able to use Angular {{}} to show the data in proper HTML format.
Angular :
//Created Student factory like this:
app.factory('Student', function($resource) {
var data = $resource('/api/students/:id', { id: '#_id' }, {
update: {
method: 'PUT'
}
});
return data;
});
//controller:
app.controller("dummy2", function($scope, $http, Student, $window){
$scope.getData = function(userID){
$window.location.assign("/api/students/"+userID);
}
)};
NodeJs:
app.use('/api', require('./routes/api'));
Thanks.

$http.get method not working on ng-submit

I want $http.get method to work when a form is submitted.
Here is my code. The object $scope.questions is being set when the method is called but the data doesn't show up in the div. Moreover, when the $http.get method is outside the signIn() function it works just fine.
$scope.signIn = function(data) {
$location.path('/profile');
var url = "database/fetch_data.php?query=";
var query = "Select * from question where userId=2";
url += query;
$http.get(url).success(function(questionData) {
$scope.questions = questionData;
console.log($scope.questions);
});
};
<div>
User Profile
<br/>Question Posted
<br/>
<input ng-model="query.title" id="value" type="text" placeholder="Search by Title..." ">
<div>
<ul>
<li ng-repeat="question in questions | filter: query ">
{{question.title}}
</li>
</ul>
</div>
<br/>
</div>
You need to move your $location.path('/profile') inside your http request. Remember that a http request is async call. You should redirect after getting the data not before.
$scope.signIn = function(data) {
var url = "database/fetch_data.php?query=";
var query = "Select * from question where userId=2";
url += query;
$http.get(url).success(function(questionData) {
$scope.questions = questionData;
console.log($scope.questions);
$location.path('/profile');
});
};
If you're redirecting to another route with a completely separate scope you will lose any scope you're setting in the success handling.
From what I'm reading you're clicking a button to do an action. After that action you're redirecting to another page with a separate controller and trying to persist the data.
Unfortunately, Angular hasn't figured out a great way to do this. The easiest way to persist data through controllers and scope is to create a service that will store it in one controller and grab it in another controller.
For instance:
$scope.signIn = function(data) {
var url = "database/fetch_data.php?query=";
var query = "Select * from question where userId=2";
url += query;
$http.get(url).success(function(questionData) {
$location.path('/profile');
storageService.store("question", questiondata)
});
};
Your new factory to persist data through:
angular.module('moduleName').factory('storageService', [
function () {
return {
store: function (key, value) {
localStorage.setItem(key, JSON.stringify(value));
},
get: function(key) {
return JSON.parse(localStorage.getItem(key));
},
remove: function(key) {
localStorage.removeItem(key);
}
}
}
]);
Other controller to access data:
$scope.question = storageService.get("question");
// remove localstorage after you've grabbed it in the new controller
storageService.remove("question");
An alternative to doing the somewhat 'hacky' way of using localStorage to persist data through controllers is to use ui-router and have a resolve on the route you're redirecting to.
For instance:
$scope.signIn = function(data) {
$state.go('profile');
};
In your route file:
.state('profile', {
url: '/profile'
controller: profileControllerName,
templateUrl: 'profileHtmlTemplate.html',
resolve: {
'questions': [function() {
var url = "database/fetch_data.php?query=";
var query = "Select * from question where userId=2";
url += query;
$http.get(url).success(function(res) {
return res.data;
});
}]
}
}
In your profile controller:
Inject your 'questions' resolve into your controller and assign `$scope.question = questions;
This will make the HTTP call as soon as you click the route, return the data if successful, then render the page. It will NOT render the page if the resolve does not return success. This will ensure your data will be loaded before you load the page that depends on that data.
I would highly recommend using services to hold your HTTP calls for specific parts of your application. If you have a GET questions, POST question, PUT question. I would create a questionService and make all my HTTP methods there so you don't have to clutter your routes. You would only have to call:
.state('profile', {
url: '/profile'
controller: profileControllerName,
templateUrl: 'profileHtmlTemplate.html',
resolve: {
'questions': [function() {
return questionService.getQuestions(id).then(function(res) {
return res.data;
})
}]
}
}

AngularJS ng-click linking to a model

I am building a small rss reader using Express(ie Jade) and Angular. I have a dropdown menu, where the menu items are populated by a list of items in a model.
Whatever the user chooses as an item, there is a rss url attached to it and it should trigger a factory.
This is the jade part:
div.btn-group
button.btn.btn-info(type='button') {{loadButtonText}}
button.btn.btn-info.dropdown-toggle(data-toggle='dropdown')
span.caret
span.sr-only Toggle Dropdown
ul.dropdown-menu(role='menu')
li(ng-repeat='rss in RSSList')
a(href='#', ng-click="feedSrc='{{rss.url}}';loadFeed($event);") {{rss.Title}}
input.form-control(type='text', autocomplete='off', placeholder="This is where your feed's url will appear" data-ng-model='feedSrc')
This is my angular controller:
var News = angular.module('myApp', []);
News.controller('FeedCtrl', ['$scope','FeedService', function($scope, Feed){
$scope.loadButtonText = 'Choose News Feed';
$scope.RSSList = [
{Title: "CNN", url: 'http://rss.cnn.com/rss/cnn_topstories.rss'},
{Title: "Reuters", url: 'http://feeds.reuters.com/news/usmarkets'}
];
$scope.loadFeed = function (e) {
Feed.parseFeed($scope.feedSrc).then(function (res) {
$scope.loadButtonText=angular.element(e.target).text();
$scope.feeds = res.data.responseData.feed.entries;
}); }}]);
News.factory('FeedService', ['$http', function($http){
return {parseFeed: function (url){
return $http.jsonp('//ajax.googleapis.com/ajax/services/feed/load?v=1.0&num=50&callback=JSON_CALLBACK&q='+encodeURIComponent(url));}}
}]);
It seems feedSrc in ng-click doesn't capture rss.url and can not be passed as argument to the parseFeed function.
I tried to pass rss.url directly into loadFeed, like this ng-click="loadFeed({{rss.url}});" and even ng-click="loadFeed('{{rss.url}}');" I didn't work either.
Simply pass it this way :
ng-click="loadFeed(rss.url)"
No need to use the {{ }} in ng-click
Why not to use just:
Jade:
a(href='#', ng-click="loadFeed(rss.url,$event)") {{rss.Title}}
Controller:
$scope.loadFeed = function (url, e) {
Feed.parseFeed(url).then(function (res) {
$scope.loadButtonText=angular.element(e.target).text();
$scope.feeds = res.data.responseData.feed.entries;
}); }}]);

Data from firebase not loading on route change, but does on refresh

I'm using angularFire with Angular to update some views but the strange thing is when I switch from view to view the data doesn't load, but when I refresh the page it does. What's going on?
WizardController:
/* initialize data */
var ref = new Firebase('https://dlwj.firebaseio.com/');
/* set data to automatically update on change */
$scope.currentLocation = $route.current.$$route.originalPath;
$scope.propertyRef = $firebase(ref);
$scope.propertyRef.$on('loaded', function(value) {
//value will be undefined when I switch views using hash routes.
//there is no issue when I just refresh on that page.
console.log(value);
$scope.propertyConfiguration = value.products;
var products = [];
for (var key in value.products) {
if (value.products.hasOwnProperty(key)) {
products.push(key);
}
}
$scope.productsArray = products;
});
console.log('Data retrieved');
Routes:
$routeProvider.when('/SharedProperties',
{
templateUrl: 'partials/SharedPropertiesPartial.html',
controller: 'WizardController'
});
$routeProvider.when('/Registration',
{
templateUrl: 'partials/Registration.html',
controller: 'WizardController'
});
$routeProvider.when('/Login',
{
templateUrl: 'partials/Login.html',
controller: 'WizardController'
});
There is no reason to download the data using a wrapper lib like $firebase (which takes care of synchronization and such) and then immediately pull that data out and put it into a different scope object.
Just declare your scope var:
$scope.products = $firebase(ref);
And to use it:
<ul>
<li ng-repeat="product in products | orderByPriority">{{product|json}}</li>
</ul>
If you need to iterate the data in a controller or service:
$scope.products = $firebase(ref);
// some time later, probably in $scope.products.$on('loaded')...
// note that $getIndex() is only useful here to get the keys in
// the order they appear in the database, otherwise, forEach($scope.products, ...)
// is sufficient
angular.forEach($scope.products.$getIndex(), function(key) {
console.log(key, $scope.products[key]);
});
If you want to use Firebase as a static database (which is quite baffling to a lover of all things real-time like myself) and not be notified each time there is a change, you can simply do the following:
angular.controller('MyController', function($timeout, $scope) {
new Firebase('<URL>').once('value', function(snap) {
$timeout(function() {
$scope.products = snap.val();
});
});
});
And then utilize it normally:
<ul>
<li ng-repeat="(key,product) in products">{{key}}: {{product|json}}</li>
</ul>

AngularJS watch service value change instead of scope inheritance

I just give a try to AngularJS. I try to do something quite simple but I'd like to do it the good way.
I got a list of items in a table which displays name and quantity for each item.
I have a form under the table.
When I click on an item name from the table I'd like the given item to be updatable through the form.
I achieve to do thing with scope inheritance as in fiddle http://jsfiddle.net/5cRte/1/
View :
<tr ng-repeat="item in items">
<td>{{item.name}}</td>
<td>{{item.quantity}}</td>
</tr>
Controllers :
function ItemListController($scope){
$scope.items = [{name:'item1', quantity:10}, {name:'item2', quantity:5}];
$scope.selectCurrentItem = function(currentItem) {
$scope.currentItem = currentItem;
}
}
function ItemFormController($scope){
$scope.$watch('currentItem', function() {
$scope.item = $scope.currentItem;
});
}
But has I read in some topics, it is not a good practice to couple controllers scopes this way, and preferably I'll wan't to use a service to store variables shared between controllers.
I was able to put a static variable in a service and retrieve it in another controller, but I can't make it updated when clicking on the item from the table, as watch not working on services variable. Have you an hint, for this ?
Thanks in advance
I don't know whether this is optimal but this what I could come up with
angular.module('myApp', []);
angular.module('myApp').factory('myService', function(){
var items = [{name:'item1', quantity:10}, {name:'item2', quantity:5}, {name:'item3', quantity:50}];
var current = {};
return {
getItems: function(){
return items;
},
setCurrentItem: function(item){
current.item = item;
},
removeCurrentItem: function(){
delete current.item;
},
getCurrent: function(){
return current;
}
}
});
function ItemListController($scope, myService){
$scope.items = myService.getItems();
$scope.selectCurrentItem = function(currentItem) {
myService.setCurrentItem(currentItem);
}
}
function ItemFormController($scope, myService){
$scope.current = myService.getCurrent();
}
Demo: Fiddle

Resources