I have two functions in my Controller.
The showEditScreen function which actually loads a user record over
$resource.get.
The updateUserDetails function which should update the user.
In the showEditScreen function everything is working. The user details are parsed over json and when looking at the $scope.user object functions like $get, $post, $update are present.
When looking at the same (also unmodified) object in the updateUserDetails function the object has changed and all the functions like $get, $post, $update and so on are missing.
This is a really weird behavior. Does anybody have an explanation for this?
When I use http.put i can save the object by the way.
console.log($scope.user) output in showEditScreen() function
Resource {$get: function, $save: function, $query: function, $remove: function, $delete: function…}
firstName: "Mista"
id: "d419375a-ba0b-4177-93cf-842e2c3e046e"
lastName: "BlaaahBlaaah1"
password: "bla"
roles: Array[2]
username: "blabla1"
__proto__: Resource
console.log($scope.user) in updateUserDetails() function:
Resource {id: "d419375a-ba0b-4177-93cf-842e2c3e046e", firstName: "Mista", lastName: "BlaaahBlaaah1", username: "blabla1", password: "bla"…}
firstName: "Mista"
id: "d419375a-ba0b-4177-93cf-842e2c3e046e"
lastName: "BlaaahBlaaah1"
password: "bla"
roles: Array[2]
username: "blabla1"
__proto__: Resource
When executing $scope.user.$update() in updateUserDetails() function:
POST http://localhost:8080/api/user/.json 405 (Request method 'POST' not supported) angular.js:9120
(anonymous function) angular.js:9120
sendReq angular.js:8977
$http angular.js:8768
Resource.(anonymous function) angular-resource.js:385
Resource.(anonymous function) angular-resource.js:431
UserCtrl.$scope.updateUserDetails controllers.js:37
(anonymous function) angular.js:6212
(anonymous function) angular.js:12751
Scope.$eval angular.js:7905
Scope.$apply angular.js:7985
$delegate.__proto__.$apply index.html:500
(anonymous function) angular.js:12750
(anonymous function) angular.js:1928
forEach angular.js:110
eventHandler angular.js:1927
HTML:
<div id="user_list" class="listview_list">
<div id="user_row" class="listview_row" ng-repeat="user in users">
<div id="user_username" class="listview_column"><span class="listview_fat"> {{user.username}}</span></div>
<div id="user_firstname" class="listview_column">{{user.firstName}}</div>
<div id="user_lastname" class="listview_column">{{user.lastName}}</div>
<button class="listview_row_button" ng-click="showEditScreen(user.id)">Edit</button>
</div>
</div>
<div id="user_edit" class="edit_form" ng-show="userEditScreenIsVisible">
<form name="edit_user">
<label>Username</label><br/>
<input name="username" ng-model="user.username" required/><br/>
<label>Firstname</label><br/>
<input name="firstName" ng-model="user.firstName" required/><br/>
<label>Lastname</label><br/>
<input name="lastName" ng-model="user.lastName" required/><br/>
<button class="button" ng-click="hideEditScreen()">Close</button>
<button class="button" ng-click="updateUserDetails()">Update</button>
</form>
</div>
Controller:
/*
* Controller to display and manipulate users.
*/
function UserCtrl($scope, $http, Users, User) {
// set edit screen to invisible by default
$scope.userEditScreenIsVisible = false;
// set new screen to invisible by default
$scope.userNewScreenIsVisible = false;
// display list with users
Users.query(
{}, //params
function (data) { //success
$scope.users = data.data;
},
function (data) { //failure
console.log("Error occurred while getting list of users");
});
// show edit screen if edit button is clicked
$scope.showEditScreen = function(id) {
$scope.user = User.get({userId: id});
console.log($scope.user);
$scope.userEditScreenIsVisible = true;
}
// hide edit screen if close button is clicked
$scope.hideEditScreen = function() {
$scope.userEditScreenIsVisible = false;
}
$scope.updateUserDetails = function() {
console.log($scope.user);
$scope.user.$update();
//$http.put("http://localhost:8080/api/user/" + $scope.user.id + ".json", $scope.user);
}
// show new screen if add button is clicked
$scope.showNewScreen = function() {
$scope.userNewScreenIsVisible = true;
}
}
Service:
angular.module('user.services', ['ngResource']).
factory('Users', function($resource) {
return $resource('http://localhost\\:8080/api/user/all.json', {}, {
query: {method:'GET', params:{}, isArray:false}
});
}).
factory('User', function($resource){
return $resource('http://localhost\\:8080/api/user/:userId.json', {}, {
get: {method:'GET'},
update: {method:'PUT'}
});
})
Issue solved!!!!
Service:
// User Service
angular.module('user.services', ['ngResource']).
factory('User', function($resource){
return $resource('/api/user/:userId', {userId: '#id'}, {
query: {method: 'GET', headers: [{'Content-Type': 'application/json'}, {'Accept' : 'application/json'}]},
get: {method:'GET', headers: [{'Content-Type': 'application/json'}, {'Accept' : 'application/json'}]},
update: {method:'PUT', headers: [{'Content-Type': 'application/json'}, {'Accept' : 'application/json'}]}
});
})
The first problem was solved by Vineet. Actually the functions $get, $post, $delete and so on were present. Just further down when expanding the log record in the Chrome Batarang environment.
My actual problem was that the default query method does not like file extensions at the end such as .json
If using file extensions following will happen when not parsing an Id:
/api/user/.json
But we would like to have following to display all users:
/api/user/
So file extensions should not be used. The Content-Type should be negotiated through the header. Then file extensions won't be necessary to determine the Content-Type.
I changed my user.service the following way:
angular.module('user.services', ['ngResource']).
factory('User', function($resource){
return $resource('http://localhost\\:8080/api/user/:userId', {userId: '#id'}, {
query: {method: 'GET', headers: [{'Content-Type': 'application/json'}, {'Accept': 'application/json'}]},
get: {method:'GET', headers: [{'Content-Type': 'application/json'}, {'Accept': 'application/json'}]},
update: {method:'PUT', headers: [{'Content-Type': 'application/json'}, {'Accept': 'application/json'}]},
create: {method:'POST', headers: [{'Content-Type': 'application/json'}, {'Accept': 'application/json'}]},
delete: {method:'DELETE', headers: [{'Content-Type': 'application/json'}, {'Accept': 'application/json'}]}
});
})
My controller looks as followed:
function UserCtrl($scope, $resource, User) {
// set edit screen to invisible by default
$scope.userModScreenIsVisible = false;
// initialize buttons as invisible
$scope.updateUserDetailsButtonIsVisible = false;
$scope.saveUserDetailsButtonIsVisible = false;
// display list with users
$scope.getList = function() {
User.query(
{}, //params
function (data) { //success
$scope.users = data.data;
},
function (data) { //failure
console.log("Error occurred while getting list of users");
});
}
$scope.getList();
// show edit screen if edit button is clicked
$scope.showEditScreen = function(id) {
$scope.user = User.get({userId: id});
$scope.updateUserDetailsButtonIsVisible = true;
$scope.userModScreenIsVisible = true;
}
// hide edit screen if close button is clicked
$scope.hideEditScreen = function() {
$scope.updateUserDetailsButtonIsVisible = false;
$scope.saveUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
}
// update a user
$scope.updateUserDetails = function() {
$scope.user.$update();
for(var i=0;i<$scope.users.length;i++) {
if($scope.users[i].id == $scope.user.id) {
angular.extend($scope.users[i], $scope.user);
break;
}
}
console.log($scope.user);
//$scope.user = User.get({userId: $scope.user.id});
$scope.updateUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
}
// show a new user screen
$scope.showNewScreen = function() {
$scope.user = new User();
$scope.saveUserDetailsButtonIsVisible = true;
$scope.userModScreenIsVisible = true;
}
// save a new user
$scope.saveUserDetails = function() {
$scope.user.$create();
$scope.users.push($scope.user);
$scope.saveUserDetailsButtonIsVisible = false;
$scope.userModScreenIsVisible = false;
}
// delete a user
$scope.deleteUser = function(id) {
$scope.user = User.get({userId: id});
$scope.user.$delete();
}
}
The HTML:
<div id="user_list" class="listview_list">
<div id="user_row" class="listview_row" ng-repeat="u in users">
<div id="user_username" class="listview_column"><span class="listview_fat">{{u.username}}</span></div>
<div id="user_firstname" class="listview_column">{{u.firstName}}</div>
<div id="user_lastname" class="listview_column">{{u.lastName}}</div>
<button class="listview_row_button" ng-click="deleteUser(u.id)">Delete</button>
<button class="listview_row_button" ng-click="showEditScreen(u.id)">Edit</button>
</div>
</div>
<div id="user_new" class="new_user">
<button class="new_user_button" ng-click="showNewScreen()">Add user</button>
</div>
<div id="user_mod" class="mod_form" ng-show="userModScreenIsVisible">
<form name="mod_user">
<label>Username</label><br/>
<input name="username" ng-model="user.username"/><br/>
<label>Firstname</label><br/>
<input name="firstName" ng-model="user.firstName"/><br/>
<label>Lastname</label><br/>
<input name="lastName" ng-model="user.lastName"/><br/>
<button class="button" ng-click="hideEditScreen()">Close</button>
<button class="button" ng-click="updateUserDetails()" ng-show="updateUserDetailsButtonIsVisible">Update</button>
<button class="button" ng-click="saveUserDetails()" ng-show="saveUserDetailsButtonIsVisible">Save</button>
</form>
</div>
Related
I am trying to send data from my Angular.js controller to Node.js backend. I succeeded in making a MongoDB entry when the request is raised.But the data is missing in the MongoDB entry. I am stuck and can't proceed with my app anymore. Can anyone give me a clear explanation why I am not able to send the form data to the Node.js.
I had put my schema of the data here:
var common = require('../common');
var inviteeSchema = common.Schema({
email: String
});
var Invite = common.conn.model('Invite', inviteeSchema);
module.exports = Invite;
I have enclosed the routing code here.
router.route('/addtoinvitelist').post(function (req, res, next) {
var invite =new Invite(req.body);
invite.save(function(err,email){
if(err) throw err;
res.json({message:"your mail id is stored in our database we will soon send you an invite"})
});
});
My HTML form goes here
<form action="#">
<div class="form-group">
<label for="subcribeNewsletter" class="control-label">INVITE FORM<br> <small>We are happy to invite you to medicoshere, So please enter your email ID in the below form.</small></label>
<div class="input-group input-group-in input-group-sm">
<div class="input-group-addon"><i class="fa fa-envelope text-belpet"></i></div>
<input class="form-control" id="subcribeNewsletter" placeholder="name#mail.com" ng-model="useremail" required>
<div class="input-group-btn">
<button type="submit" class="btn btn-default text-belpet" ng-click="AddToInviteList(useremail)"><strong>OK</strong></button>
</div>
</div>
</div><!-- /.form-group -->
</form><!-- /form -->
my angular service functions goes here
`this.AddToInviteList = function (email, cb) {
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}, // set the headers so angular passing info as form data (not request payload)
data:"email"
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
}`
Controller function is here
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.email = {};
$scope.AddToInviteList = function () {
UserServices.AddToInviteList($scope.email, function (dataresponse) {
console.log(dataresponse);
})
}
});
Pass email as json object { 'email' : email }.
Just try this code:
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data:{ 'email' : email }
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
Controller :
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.AddToInviteList = function () {
$scope.user = {
email : $scope.useremail
};
UserServices.AddToInviteList($scope.user, function (dataresponse) {
console.log(dataresponse);
})
}
});
In server side you can access the email by calling 'req.body.email'
Change your model name in HTML input element with email and send request as
$http({
method: 'POST',
url: "http://localhost:3000/users/addtoinvitelist",
headers: {
'Content-Type': 'application/json'
},
data:{ 'email' : email }
}).success(function (data) {
console.log("email is posted sucessfully" + data);
cb(data);
})
and get it at backend side as
req.body.email
I think that should work!
Update
App.controller('InviteController', function ($scope, $rootScope, $routeParams, $location, UserServices) {
$scope.init = function () {
console.log("hii this is a test ")
};
$scope.AddToInviteList = function () {
UserServices.AddToInviteList($scope.email, function (dataresponse) {
console.log(dataresponse);
})
}
I have a form, it sends data to a database, but it makes it twice.
Here is the code of controller and example of html view.
$scope.addEvent = function(type) {
if (!$scope.sentAdd) {
$scope.newEvent.admission = type;
$scope.newEvent.customer_id = $scope.curUID;
console.log($scope.newEvent);
$http({
url: '/addEvent',
method: "POST",
data: $.param($scope.newEvent),
headers: {
'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
}
})
.success(function(data){
//console.log(data);
$scope.newEvent = $scope.cleanEvent;
$scope.addEventForm.$setPristine();
$scope.sentType = type;
$scope.sentAdd = true;
$.fancybox.close();
$.fancybox.open({ href: '#eventSuccess', type: 'inline' });
});
}
};
<form name="addEventForm" novalidate>
<input type="text" ng-model="text">
<a ng-click="addEvent('Paid')">Add Paid Event</a><br>
<a ng-click="addEvent('Free')">Add Free Event</a>
</form>
.controller('LoginConnect', ['$scope', 'connecting',
function(connecting, $scope){
$scope.user = {};
var inputLogin = $scope.user.login;
var inputPassword = $scope.user.password;
$scope.connect = function (){
connecting(ConnectingFactory);
};
}
])
.factory('connecting', ['$http','$q', function ($http,$q,inputLogin, inputPassword, ConnectingFactory){
var ConnectingFactory = {};
console.log(ConnectingFactory);
ConnectingFactory.login = function(){
var deferred = $q.defer();
$http({
method: 'POST',
url: "http://api.tiime-ae.fr/0.1/request/login.php",
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data: {login: inputLogin, password: inputPassword}
})
.success(function(result){
deferred.resolve(result);
var promise = deferred.promise;
promise.then(function(result){
console.log(result);
// jsonTab = angular.fromJson(result);
// $scope.result = result["data"];
// $scope.user.token = result["data"];
});
})
};
return ConnectingFactory;
}]);
;
And here the HTML :
<!-- User Connection -->
<form name="userConnect" ng-submit="connect()" novalidate ng-controller="LoginConnect">
<label>
Enter your name:
<input type="text"
name="myEmail"
ng-model="user.login"
/>
</label>
<label>
Enter your Password:
<input type="password"
name="password"
ng-model="user.password"
/>
</label>
<input type="submit" value="Connection">
<p>resultat : {{result}}</p>
<p ng-model="user.token">
token : {{mytoken}}
</p>
<p ng-model="user.datab">
datas : {{datab}}
</p>
<br><br><br>
</form>
Hi, I m new in Angular Js developpement, i have no error but not any data in sent to the API. I think their is no link between my function "connect()" and the factory. Could you help me pls ?
Don't use the success method either way.Both methods have been deprecated.
The $http legacy promise methods success and error have been
deprecated. Use the standard then method instead. If
$httpProvider.useLegacyPromiseExtensions is set to false then these
methods will throw $http/legacy error.
Here is the shortcut method
$http.post('/someUrl', data, config).then(successCallback, errorCallback);
Here is a longer GET method sample
$http({
method: 'GET',
url: '/someUrl'
}).then(function successCallback(response) {
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
Official Documentation
Regarding the factory , call it correctly as ConnectingFactory.login().
Also, the order here is incorrect, as pointed out by Harry.
['$scope', 'connecting',
function(connecting, $scope){
I have this template in my project:
<script type="text/ng-template" id="/challenges.html" ng-controller="ChallengeCtrl">
<main>
<h3 class="headingregister">Start challenge reeks</h3>
{{getUser()}}
<form name="startChallengesForm" ng-submit="getChallenges()">
<button type="submit" class="btn btn-primary">Doe de challenges!</button>
</form>
</main>
</script>
The getUser() function should display the current logged in users info.
This is the ChallengeCtrl:
app.controller('ChallengeCtrl', ['$scope', 'auth',
function($scope, auth) {
$scope.isLoggedIn = auth.isLoggedIn;
$scope.currentUser = auth.currentUser;
$scope.logOut = auth.logOut;
$scope.getUser = function(){
auth.getUser(auth.currentUser()).getValue(function(value){
return value;
});
};
}]);
this is auth.getUser:
auth.getUser = function(usr){
return{
getValue: function(callback){
$http({
method: 'POST',
url:'http://groep6api.herokuapp.com/user',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
transformRequest: function(obj) {
var str = [];
for(var p in obj)
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
return str.join("&");
},
data : {username: usr}
}).then(function (result) {
//return result.data;
callback(result.data);
});
}
}
}
the problem is when I run the page, I see in developer tools that the function is being called over and over again, it should only display the users info.
How can I accomplish this?
Function calls in templates get executed each digest cycle. Simply fetch the user once in your controller and assign the value to the scope
auth.getUser(auth.currentUser()).getValue(function(value){
$scope.user = value;
});
and in your template, instead of {{getUser()}}
{{user}}
PROBLEM
Hello! I want to delete record using angular. So that must look like that: I click button "X" (delete) and record must be deleted.
WHAT I GOT FOR NOW
I don't know if all is correct, but there is my code:
html
<div ng-repeat="lists in listsdata.lists">
<div id="DIV_24" close-on-outside-click="div.popup_information">
<button ng-click="lists.show = !lists.show" id="MORE_BUTTON">:</button>
<div class="popup_information" ng-show="lists.show">
<button id="DELETE_BUTTON" ng-click="del_list()">X</button>
<a href="">
<button id="EDIT_BUTTON">E</button>
</a>
</div>
<a href="#/{{lists.id}}">
<div id="DIV_25">
{{lists.name}}
</div>
<div id="DIV_26">
</div>
</div></a>
</div>
angular
myApp.controller('listsController', ['$scope', '$log', '$http',
function($scope, $log, $http){
$http({
method: 'GET',
url: 'http://localhost/anydocopy/public/lists'
})
.success(function (d) {
console.log(d);
$scope.listsdata = d;
});
$scope.key = function($event){
console.log($event.keyCode);
if ($event.keyCode == 13) {
var list = {
name: $scope.listname
};
$scope.listname = '';
$http({
method: 'POST',
url: 'http://localhost/anydocopy/public/lists',
data: list
})
.success(function () {
console.log('true');
$http({
method: 'GET',
url: 'http://localhost/anydocopy/public/lists'
})
.success(function (d) {
console.log(d);
$scope.listsdata = d;
});
})
.error(function () {
console.log('false');
});
}};
$scope.del_list = function () {
$http({
method: 'DELETE',
url: 'http://localhost/anydocopy/public/lists/'+ $scope.listsdata.lists.id
});
console.log($scope.listsdata.lists)
}
}]);
laravel controller
public function delete($id)
{
$response['lists'] = Lists::findorfail($id)->delete();
return Response($response, 201);
}
laravel route
Route::delete('lists/{id}', 'ListsController#delete');
So for now when I click button, I cant set right url in agular function, because I can't get that id from $scope.listsdata.. I can get all array, but how to get only id I want? So if I click on button what is on list with id=1 so in angular function must work like method=delete and url= url+id. How to do that, please help.
Pass what you want to delete as argument. And rename lists to list, since it represents a single list:
<div ng-repeat="list in listsdata.lists">
...
<button ng-click="del_list(list)">X</button>
and
$scope.del_list = function(listToDelete) {
$http({
method: 'DELETE',
url: 'http://localhost/anydocopy/public/lists/'+ listToDelete.id
});
}
Pass argument in ng-click function you want to delete like
<div ng-repeat="list in listsdata.lists">
...
<button ng-click="del_list(list)">X</button>
</div>
you Delete function looks ike
$scope.del_list = function(selectedItem) {
$http({
method: 'DELETE',
url: 'http://localhost/anydocopy/public/lists/'+ selectedItem.id
});
console.log($scope.listsdata.lists)
}