watch and apply changes to object in angular js service - javascript

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;
}
}])

Related

API, angularJS, to get datas

I never done angularJS from all my life and i am lost.
So i have done this file, to obtain datas from an api with a filter of time.
forecast.js
(function() {
angular.module('application').factory('Forecast', ['$http', '$q', function($http, $q){
var ApiAddr = "api.com/";
forecast.getResults = function(timeStart, timeEnd){
// We map application varaible names with API param names
var httpParams = {
type: "global",
time: "minute",
tsmin: timeStart,
tsmax: timeEnd
};
return $http.get(apiAddr, {
params: httpParams,
cache: true
}).then(function(data){
return data;
},
function(response){
console.log(
"HTTP request "+ApiAddr+
" (with parameters tsmin="+httpParams.tsmin+", tsmax="+httpParams.tsmax+
", type="+httpParams.type+", time="+httpParams.time+
(httpParams.motive ? ", motive="+httpParams.motive : "")+
(httpParams.vector ? ", vector="+httpParams.vector : "")+
(httpParams.media ? ", media="+httpParams.media : "")+
") failed with "+response.status
);
return $q.reject(response);
}
);
}];
But i have no idea to make a controller adapter to this. What type of controller i can do ?
Every exemple are based on a fixed json file, with no parameters.
Moreover, i want, in HTML to imput the time filter, but i have totaly no idea of what to do for this. The example i have seen were to get datas, no to send.
Ps : I have made 2 days of research about this, i have never done front end programming in my life.
(function() {
angular.module('application', [])
.factory('Forecast', ['$http', '$q', function($http, $q) {
var apiaddress = 'api.com';
var forecast = {};
forecast.getResults = function(timeStart, timeEnd) {
// We map application varaible names with API param names
var httpParams = {
type: "global",
time: "minute",
tsmin: timeStart,
tsmax: timeEnd
};
return $http.get(apiaddress, {
params: httpParams,
cache: true
}).then(function(result) {
return result.data;
});
};
return forecast;
}])
.controller('SampleCtrl', ['$scope', 'Forecast', function($scope, Forecast) {
$scope.forecastReport = '';
$scope.getForecast = function() {
Forecast.getResults($scope.timeStart, $scope.timeEnd)
.then(function(report) {
$scope.result = report;
}).catch(function(err) {
$scope.result = '';
console.error('Unable to fetch forecast report: ' + err);
});
};
}]);
})();
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="application" ng-controller="SampleCtrl">
<label>Time Start:
<input type="text" ng-model="timeStart"/></label>
<label>Time End:
<input type="text" ng-model="timeEnd"/></label>
<button ng-click="getForecast()">Get Forecast</button>
<hr/>
<div>
<b>Forecast Result:</b>
</div>
<pre>{{forecastReport | json}}</pre>
</div>
Just inject the factory into your controller like this:
var app = angular.module('application');
app.controller('myController',
['$scope', 'Forecast', function($scope, Forecast) { /* access to Forecast*/}]);
Or with a component (cleaner):
app.component('myComponentCtrl', {
templateUrl: 'template.html'
controller: myComponentCtrl
})
myComponentCtrl.$inject = ['$scope', 'Forecast'];
function myComponentCtrl($scope, Forecast) {/* ... */ }

Pass datas between routes angularjs/expressjs

I have a form, and when I submit it, another form is displayed with radio buttons which are other datas. I select one and submit it. I want the data to be displayed in another page but it doesn't display anything with what I've done.
So there is the /form route, and I want to be redirect on the /confirmation route with my datas after the last submit.
Bellow is my formController in angularjs
.controller('formController', ['$scope', '$http', '$location', function($scope, $http, $location) {
$scope.pageClass = 'form';
$scope.firstName = '';
$scope.lastName = '';
$scope.email = '';
$scope.departure = '';
$scope.destination = '';
$scope.submitFirstForm = function() {
$http.post('/form', {
firstName: $scope.firstName,
lastName: $scope.lastName,
email: $scope.email,
departure: $scope.departure,
destination: $scope.destination,
}).then(function(res) {
$scope.response = res.data;
});
}
$scope.submitConfirmationForm = function(flight){
$http.post('/confirmation', {
departure: $scope.departure,
destination: $scope.destination
}).then(function(res) {
$scope.otherResponse = res.data;
$location.path("/confirmation");
});
};
}]);
Bellow is my express post function only for the /CONFIRMATION route
app.post("/confirmation",function(req,res)
{
var departure=req.body.departure;
var destination=req.body.destination;
otherResponse = {
"confirmation": [{
"departure": departure,
"destination": destination,
"msg": "MSG OK",
}]
};
res.json(otherResponse);
});
Finally, bellow my confirmation.html to see what is going on with my json otherReponse
<pre>
{{otherResponse | json}}
</pre>
You are not passing the 'value', you need to do something like this:
$location.path('/confirm/').search({param: 'otherResponse'});
$location methods are chainable.
this produce :
/confirm/?param=otherResponse
Check the doc for $location

ng-show - using a service as a scope parameter

I'm writing an angular 1.5.0-rc0 application using bootstrap for a nav bar component.
I want to show the user an added items to his navigation bar if his user group id is 1.
first I created a service:
app.factory('UserService', function() {
return {
userGroupId : null
};
});
I created the nav bar as a directive, so i included it in the main html file
<nav-bar></nav-bar>
and the nav-bar directive code:
(function () {
angular.module('myalcoholist').directive('navBar', function () {
return {
restrict: 'E',
templateUrl: 'views/nav.html',
controller: ['$scope','$auth', 'UserService',function ($scope,$auth,UserService) {
$scope.user=UserService;
$scope.isAuthenticated = function()
{
return $auth.isAuthenticated();
};
}]
}
});
})();
as you can see I set $scope.user as the returned object from UserService.
in my login controller, after a successful login I set the userGroupId.
angular.module('myalcoholist').controller('LoginController',['$scope','$auth','$location', 'toastr','UserService',function ($scope,$auth,$location,toastr,UserService) {
$scope.authenticate = function (provider) {
$auth.authenticate(provider).then(function (data) {
var accessToken = data.data.token;
apiKey=accessToken;
UserService.userGroupId=data.data.user_group_id;
...
now.. my nav-bar template file is as the following code:
<li ng-show="user.userGroupId == 1">
Admin Drinks
</li>
even after the authentication, when I uset userGroupId to 1 the element is still not shown.
any ideas?
update
I debugged and noticed that UserService.userGroupId is still null. so
I changed the UserService to have the following code:
app.factory('UserService', function() {
var user = {userGroupId:null};
return {
setUserGroupId: function (userGroupId) {
user.userGroupId=setUserGroupId;
},
getUserGroupId: function () {
return user.userGroupId;
}
};
});
in my LoginController I now try to execute setUserGroupId:
angular.module('myalcoholist').controller('LoginController',['$scope','$auth','$location', 'toastr','UserService',function ($scope,$auth,$location,toastr,UserService) {
$scope.authenticate = function (provider) {
$auth.authenticate(provider).then(function (data) {
var accessToken = data.data.token;
apiKey=accessToken;
UserService.setUserGroupId(data.data.user_group_id);
...
when I debug i see that userService is an object with two functions as I defined, but when the javascript chrome debugger tries to execute this line:
UserService.setUserGroupId(data.data.user_group_id);
I get the following error:
ReferenceError: setUserGroupId is not defined
at Object.setUserGroupId (app.js:21)
at login-controller.js:12
at angular.js:15287
at m.$eval (angular.js:16554)
at m.$digest (angular.js:16372)
at m.$apply (angular.js:16662)
at g (angular.js:11033)
at t (angular.js:11231)
at XMLHttpRequest.v.onload (angular.js:11172)
I have created a fiddle showcasing your requirement (as close as possible), and it seems to work fine.
http://jsfiddle.net/HB7LU/21493/
My guess is that you aren't actually setting the value when you think you are, and will likely require some debugging. Here is the code for brevity.
HTML
<div ng-controller="MyCtrl">
<div ng-click="clicked()">
Click ME, {{user.value}}!
</div>
<test-dir></test-dir>
</div>
JS
angular.module('myApp',[])
.service('TestService', function(){
return {
value: 2
};
})
.directive('testDir', function(){
return {
restrict: 'E',
template: '<div ng-show="user.value === 1">Here is some text</div><div>Some more always showing</div>',
controller: function ($scope, TestService) {
$scope.user = TestService;
}
};
})
.controller('MyCtrl', function($scope, TestService){
$scope.user = TestService;
$scope.clicked = function(){
TestService.value = 1;
};
});

How to show buttons with user authentication in AngularJS?

Currently I am working on my master project. My application is online portfolio management. User can register on app and create profiles. Now i want to give Edit and Delete buttons on the profile view. But just the users who have created the profile are able to see this buttons. For example, if i am a user of app then only i can see the edit and delete buttons on my profile and i can only see the other user's profile.
I am new in AngularJS. It looks easy but still did not work for me. I have a different views of view profile and edit profile. But i have just one controller for both of it.
This is how my view profile code looks like,
HTML
<section data-ng-controller="ProfilesController as profilesCtrl">
<div class="modal-header">
<div>
<h1>{{profile.firstname}} {{profile.lastname}}</h1>
</div>
<div class="pull-right">
<button class="btn-success btn-lg" type="button" data-ng-click="profilesCtrl.modalUpdate('lg', profile)">Edit</button>
<button class="btn-danger btn-lg" type="button" data-ng-click="profilesCtrl.remove(profile)">
<i class="glyphicon glyphicon-trash">
</i>
</button>
</div>
</div>
</section>
Controller
profilesApp.controller('ProfilesController', ['$scope', '$stateParams', '$location', 'Authentication', 'Profiles', '$modal', '$log',
function($scope, $stateParams, $location, Authentication, Profiles, $modal, $log) {
this.authentication = Authentication;
// Find a list of Profiles
this.profiles = Profiles.query();
// open a modal window to view single profile
this.modalview = function(size, selectedProfile) {
var modalInstance = $modal.open({
templateUrl: 'modules/profiles/views/view-profile.client.view.html',
controller: function($scope, $modalInstance, profile) {
$scope.profile = profile;
console.log(profile);
$scope.ok = function() {
$modalInstance.close($scope.profile);
};
},
size: size,
resolve: {
profile: function() {
return selectedProfile;
}
}
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
// open a modal window to update single profile
this.modalUpdate = function(size, selectedProfile) {
var modalInstance = $modal.open({
templateUrl: 'modules/profiles/views/edit-profile.client.view.html',
controller: function($scope, $modalInstance, profile) {
$scope.profile = profile;
$scope.ok = function() {
$modalInstance.close($scope.profile);
};
$scope.cancel = function() {
$modalInstance.dismiss('cancel');
};
},
size: size
});
modalInstance.result.then(function(selectedItem) {
$scope.selected = selectedItem;
}, function() {
$log.info('Modal dismissed at: ' + new Date());
});
};
// Remove existing Profile
this.remove = function(profile) {
if (profile) {
profile.$remove();
for (var i in this.profiles) {
if (this.profiles[i] === profile) {
this.profiles.splice(i, 1);
}
}
} else {
this.profile.$remove(function() {
$location.path('modules/profiles/views/list-profiles.client.view.html');
});
}
};
// Update existing Profile
this.update = function(updatedProfile) {
var profile = updatedProfile;
profile.$update(function() {}, function(errorResponse) {
$scope.error = errorResponse.data.message;
});
};
}
]);
Please suggest me some way, how can i fix this issue? Any help would appreciated.
you can use a directive like this:
<button access-level="canEdit">Edit</button>
and your directive is bound to accessLevel:
angular.module("app")
.directive('accessLevel', ['AuthService', 'AUTH_EVENTS', function (authService, authEvents) {
return {
restrict: 'A',
link: function ($scope, element, attrs) {
var accessLevel;
attrs.$observe('accessLevel', function (acl) {
if (acl) {
accessLevel = acl;
updateCss();
}
});
$scope.$on("auth-change", function (event, data) {
switch (data) {
case authEvents.logoutSuccess:
case authEvents.loginSuccess:
updateCss();
break;
case authEvents.notAuthorized:
default:
}
});
function updateCss() {
if (accessLevel) {
if (!authService.isAuthorized(accessLevel)) {
switch (element[0].nodeName) {
case "A":
element.hide();
break;
default:
element.attr("disabled", "disabled");
break;
}
} else {
switch (element[0].nodeName) {
case "A":
element.show();
break;
default:
element.removeAttr("disabled");
break;
}
}
}
}
}
}
}]);
this is a little bit more than what you need, but gives you an idea what you can achieve. (and you have to write your auth service etc.)
as example here is a part of my auth service:
angular.module('app')
.factory("AuthService", ["$rootScope", "$http", "AuthSession", "AUTH_EVENTS", function ($rootScope, $http, AuthSession, AUTH_EVENTS) {
AuthSession.load();
$rootScope.$on('$stateChangeStart', function (event, nextState) {
if (nextState.data && nextState.data.accessLevel && !service.isAuthorized(nextState.data.accessLevel)) {
event.preventDefault();
$rootScope.$broadcast('auth-change', AUTH_EVENTS.loginRequired, nextState.name);
}
});
var service = {
login: function (credentials) {
return $http
.post('/api/account/login', credentials)
.success(function (data, status) {
if ((status < 200 || status >= 300) && data.length >= 1) {
$rootScope.$broadcast("auth-change", AUTH_EVENTS.loginFailed);
return;
}
AuthSession.create(data.AccessToken, data.User);
$rootScope.$broadcast("auth-change", AUTH_EVENTS.loginSuccess);
}).error(function (data, status) {
$rootScope.$broadcast("auth-change", AUTH_EVENTS.loginFailed);
});
},
logout: function () {
AuthSession.destroy();
$rootScope.$broadcast("auth-change", AUTH_EVENTS.logoutSuccess);
},
isAuthenticated: function () {
return (AuthSession.token !== null);
},
isAuthorized: function (accessLevel) {
if (!accessLevel) return true;
return (this.isAuthenticated() && AuthSession.user.UserRoles.indexOf(accessLevel) !== -1);
}
}
return service;
}]);
this service retrieves a bearer token from the server and stores it in the authsession service. the user roles are also stored beside of other user information. since the backend is also secured, one who changes the user roles on the client, can't write to the backend. (everything on client side is just for the look and feel of the user)
Two ways :
Once the profile is created, let the isProfileCreated (you need to make one) column in user details table be updated. On angular load, call and check whether is profile created. use ng-show to show (edit and delete button)if it is true.
Or else, if you are going to edit, anyways you need to get the profile details from the table. in that case, let your server send a false if no profile is created or an json object if created.
In your controller use
if(angular.isObject(profile)){
$scope.showeditbutton = true;
$scope.showdeletebutton = true;
}

How to update model using angularjs, Django,Django rest framework

I have such json representation of a post by its id:
http://127.0.0.1:8000/update/1?format=json
{"title": "about me", "content": "I like program", "created": "2014-11-29T18:07:18.173Z", "rating": 1, "id": 1}
I try to update rating by button click:
<button ng-click="click(post.id)">Click me</button>
I have such javascript code:
<script>
var demoApp = angular.module('demoApp',['ngResource']);
demoApp.controller( 'AllPosts', function ($scope, $http)
{
$http.get('/blogpost/?format=json').success(function(data,status,headers,config)
{
$scope.posts = data.results;
$scope.predicate = '-title';
$scope.click = function(post_id, $resource){
var Post = $resource('/update/:PostId ',{PostId:post_id,format:'json'} );
post = Post.get({PostId:post_id}, function() {
post.rating = post.rating+ 1 ;
post.$save();
});
};
}).error(function(data,status,headers,config)
{} )
;})
</script>
Peharps i have mistake because in json i have a single object. But i dont really know
Besides i have such view to have a json by certain post by its id:
class UpdateModel(generics.RetrieveUpdateDestroyAPIView):
lookup_field = 'id'
queryset = BlogPost.objects.all()
serializer_class = BlogPostSerializer
permission_classes = (AllowAny,)
A quick tidy up of your script tag shows that you are only defining the function click if the http call was successful.
I would suggest moving the definition of the click method outside of the success callback.
You may also be running into a race condition that the click function has not been defined before clicking the actual button. Regardless you will want to move that function definition to where the controller is actually created.
Suggested edits (moved click definition outside of http call response):
var demoApp = angular.module('demoApp', ['ngResource']);
demoApp.controller('AllPosts', function($scope, $http, $resource) {
$scope.click = function(post_id) {
var Post = $resource('/update/:PostId ', {
PostId: post_id,
salutation: 'json'
});
post = Post.get({
PostId: post_id
}, function() {
post.rating = post.rating + 1;
post.$save();
});
};
$http.get('/blogpost/?format=json').success(function(data, status, headers, config) {
$scope.posts = data.results;
$scope.predicate = '-title';
}).error(function(data, status, headers, config) {});
})
Updates:
Injected $resource into the controller
Removed $resource from click function params

Categories