I have an Edit button on my event-detail page that goes to a new page where user can update the current selected event. I have no trouble using GET to get single/all events and POST to create new event. But I'm stuck on updating existing event and constantly get 404 error: PUT http://localhost:3000/api/events 404 (Not Found)
On my server route I have:
//return event-details
app.get('/api/events/:id', events.getEventById);
//update event
app.put('/api/events/:id', events.updateCurrentEvent);
Server side event controller:
exports.updateCurrentEvent = function(req, res) {
Event.findById(req.params.id, req.body, function(err, event) {
var event = req.body;
if(!event) {
res.statusCode = 404;
res.send({ error: 'Not found'});
}
event.title = req.body.title;
event.desc = req.body.desc;
event.date = req.body.date;
event.duration = req.body.duration;
event.address = req.body.address;
event.city = req.body.city;
event.state = req.body.state;
event.save(function (err) {
if (!err) {
log.info("event updated");
res.send({ status: 'OK', event:event });
} else {
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});
});
My $resource service:
app.factory('mvEvent', function($resource) {
var EventResource = $resource('/api/events/:_id', {_id: "#id"}, {
update: {method:'PUT', isArray:false}
});
return EventResource;
});
my client-side controller:
angular.module('app').controller('mvUpdateEventCtrl', function($scope, $routeParams, $location, mvEvent) {
$scope.event = mvEvent.get({_id:$routeParams.id})
.$promise
.then(function(event) {
$scope.event = event;
console.log($scope.event);
$scope.title =$scope.event.title;
$scope.desc = $scope.event.desc;
$scope.date = $scope.event.date;
$scope.duration = $scope.event.duration;
$scope.address = $scope.event.address;
$scope.city = $scope.event.city;
$scope.state = $scope.event.state;
});
$scope.updateEvent = function() {
$scope.event.$update(function() {
}, function(error) {
$scope.error = error.data.message;
});
}
});
My client side routes:
var app = angular.module('app', ['ngResource', 'ngRoute', 'ui.bootstrap']);
app.config(function($routeProvider, $locationProvider){
$locationProvider.html5Mode(true);
$routeProvider
//events route
.when('/events', {
templateUrl: '/partials/events/event-list',
controller: 'mvEventListCtrl'
})
//events detail route
.when('/events/:id', {
templateUrl: '/partials/events/event-details',
controller: 'mvEventDetailsCtrl'
})
//update event route
.when('/events/:id/update', {
templateUrl: '/partials/admin/event-update',
controller: 'mvUpdateEventCtrl'
})
});
Getting the event details showing in the each text field is as far as I can get. As soon as I hit 'Update event' Button I get 404 error and it seems to lie somewhere in my server side code. I've seen quite a bit of different approaches implementing PUT request, with or without routeParams, using findById then save or findByIdAndUpdate. I'm wondering if there is a standard way to do this. Thanks in advance!!
Remove the line var event = req.body; from your server side controller. Firstly, it is not required. Secondly, it is same as the name of the document returned by Event.findById callback, and that's getting overridden by the variable declaration.
exports.updateCurrentEvent = function(req, res) {
Event.findById(req.params.id, req.body, function(err, event) {
var event = req.body; // <<==== Remove this line
if(!event) {
res.statusCode = 404;
res.send({ error: 'Not found'});
}
event.title = req.body.title;
event.desc = req.body.desc;
event.date = req.body.date;
event.duration = req.body.duration;
event.address = req.body.address;
event.city = req.body.city;
event.state = req.body.state;
event.save(function (err) {
if (!err) {
log.info("event updated");
res.send({ status: 'OK', event:event });
} else {
if(err.name == 'ValidationError') {
res.statusCode = 400;
res.send({ error: 'Validation error' });
} else {
res.statusCode = 500;
res.send({ error: 'Server error' });
}
log.error('Internal error(%d): %s',res.statusCode,err.message);
}
});
});
}
Related
I want to delete all data in my database by a single click.but it gives
"DELETE http://localhost:8080/api/deleteAll 404 (Not Found)".
Can anyone help with this?
Below codes are my attempt.
Controller
$scope.deleteAllData = function () {
Event.deleteAll()
.success(function(){
console.log("All Deleted");
})
.error(function (error) {
$scope.status = 'Unable to load event data: ';
});
};
Service
deleteAll : function() {
return $http.delete('/api/deleteAll');
},
Route
var filesReadUploads = require('./models/readUploadFile');
app.delete('/api/deleteAll', function(req, res) {
filesReadUploads.remove({},function(err) {
if (err) {
console.log(err)
} else {
res.end('success');
}
});
});
Thanks
I am trying to get the FB.logout() functionality working.
Then error I get is FB.logout() called without an access token.
so I googled around to find some solutions. So I found that we have to get the status and try then. So when I try to getLoginStatus(). the authResponse is Null, status is unknown.
So I don't know what's the reason that I am not getting the authResponse.
I am attaching my code.
Controller.js
app.controller("dashboardCtrl",["$scope","authFactory","$location",function($scope,authFactory,$location){
var userObj = authFactory.getUserObj(userObj);
console.log(userObj);
var accessToken = authFactory.getAccessToken();
console.log(accessToken);
$scope.accessToken = accessToken;
$scope.FBout = function(){
FB.getLoginStatus(function(response) {
console.log(response);
if (response.status === 'connected') {
var uid = response.authResponse.userID;
var accessToken = response.authResponse.accessToken;
FB.logout(function(response) {
authFactory.clearCookie();
});
} else if (response.status === 'not_authorized') {
} else {
}
});
};
}]);
factory.js
app.factory("authFactory",["$cookies","$location",function($cookies,$location){
var authFactory = {};
authFactory.setAccessToken = function(accessToken){
$cookies.put("accessToken",accessToken);
}
authFactory.getAccessToken = function(){
return $cookies.get("accessToken");
}
authFactory.getUserObj = function(){
var userObj = $cookies.get('userObj');
if(userObj){
return userObj;
}
else {
console.log("error");
}
}
authFactory.clearCookie = function(){
$cookies.remove("accessToken");
$location.path("/")
}
return authFactory;
}]);
I am not able to logout and redirect to someother page. I am stuck, I have accesstoken, and user object in the cookie.
I am sure I have unchecked the thirdparty app access thing in chrome settings.
Updating with another controller where I logged in, which might be required.
app.controller('homeCtrl',["$scope","authFactory","$location","$cookieStore",function($scope,authFactory,$location,$cookieStore){
$scope.name = "login Please";
$scope.FBLogin = function(){
FB.login(function(response) {
if (response.authResponse) {
console.log('Welcome! Fetching your information.... ');
FB.api('/me', function(response) {
console.log('Good to see you, ' + response.name + '.');
$cookieStore.put("userObj",response);
var accessToken = FB.getAuthResponse().accessToken;
authFactory.setAccessToken(accessToken);
$location.path("/dashboard");
$scope.$apply();
});
} else {
console.log('User cancelled login or did not fully authorize.');
}
});
};
}]);
this is my Route.js
app.config(["$routeProvider",function($routeProvider){
$routeProvider
.when("/",{
templateUrl : 'views/home/login.html',
controller : 'homeCtrl'
})
.when("/dashboard",{
templateUrl : 'views/home/dashboard.html',
controller : 'dashboardCtrl',
authenticated : true
})
.otherwise('/',{
templateUrl : 'views/home/login.html',
controller : 'homeCtrl'
})
}]);
app.run(["$rootScope","$location","authFactory",function($rootScope,$location,authFactory){
$rootScope.$on('$routeChangeStart',function(event,next,current){
if(next.$$route.authenticated){
var userAuth = authFactory.getAccessToken();
if(!userAuth){
$location.path('/');
}
}
});
}]);
Try to disable caching in FB.getLoginStatus:
FB.getLoginStatus(function(response) {
if (response.status === 'connected') {
FB.logout(function(response) {
authFactory.clearCookie();
});
}
}, true);
More information: https://developers.facebook.com/docs/reference/javascript/FB.getLoginStatus#servers
I had the same problem, try this one:
FB.api(
'/me/permissions',
'DELETE',
{},
function(response) {
// Here fb should remove the token.
// response should be "success: true"
FB.logout(() => {
// Here logout.
});
}
);
when I click logout button, its changing the state, but not refreshing the page, because of this, my login page text boxes still having entered data. and If i loggIn with new data, Property details http request not pulling the new data.
I tried, $location.path , $state.go but no use,
can any one help me please.
Login controller
.controller('LoginCtrl', function($scope, $rootScope, AuthenticationService,ClientDetails, $ionicPopup, $state) {
$scope.data = { clientId: '', lastName: '', email: ''};
$scope.login = function () {
AuthenticationService.Login($scope.data.clientId, $scope.data.lastName, $scope.data.email, function(response) {
if(response.success) {
ClientDetails.setDetails(response.data);
$state.go('app.home');
console.log(response);
} else {
$scope.error = response.message;
var alertPopup = $ionicPopup.alert({
title: 'Login failed!',
template: $scope.error
});
}
});
};
})
getting properties through service:
.factory('PropertyDetails',
['$http', '$rootScope',
function ( $http, $rootScope) {
var clientId = $rootScope.globals.clientDetails.ClientId;
var service = {};
service.getProperties = function(callback){
$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
var data = ''; var status = ''; var message = '';
var response = {};
var Request = $http({
method: 'GET',
url: 'http://example.com/'+clientId,
data: data
})
Request.success(function(jdata, headers) {
if( headers === 200 ){
if(typeof jdata == 'object'){
status = jdata.Status;
message = jdata.Message;
data = jdata.Data;
$rootScope.globals.properties = data;
}else{
status = false;
message = "Response data is not a object!";
}
}else{
status = false;
message = "Something went wrong!";
}
//response = { success : status, message : message, data: data };
response = { success : status, message : message, data: $rootScope.globals.properties };
callback(response);
//callback($rootScope.globals.properties);
})
Request.error(function(data, headers){
if(typeof data == 'object'){
message = data.Message;
}else{
message = "Client not found.";
}
response = { success : false, message : message };
callback(response);
});
};
service.clearDetails = function(){
$rootScope.globals.properties = {};
};
return service;
}])
My logout controller:
.controller('menuCtrl', function($scope, $rootScope, ClientDetails, PropertyDetails,$timeout,$ionicHistory, $state,$location){
$scope.logOut = function(){
ClientDetails.clearDetails();
PropertyDetails.clearDetails();
$timeout(function () {
$ionicHistory.clearCache();
$ionicHistory.clearHistory();
$ionicHistory.nextViewOptions({ disableBack: true, historyRoot: true });
$state.go('login');
}, 30);
}
})
Thank you
Many Way to clear textbox first of controller call one time to load in ionic if you want to reload again data you used
$scope.$on('$ionicView.enter', function() {
//here some code
});
above code when you open page this code is running every time[load controller].
its simple way.
I am building an app using ionic and parse. I am updating a boolean in parse based on a click. Everything works on parse end, I see the user object updated in the console after the function runs, however the scope variable is not updating until user logs out, comes back to the page, and then usually has to even refresh again just to see the $scope.isInstagramLinked updated to its true value.
Controller
var app = angular.module('myApp.controllers.account', []);
app.controller('AccountCtrl', function ($scope, $state, $cordovaOauth, AuthService) {
$scope.isInstagramLinked = AuthService.user.attributes.is_instagram_linked;
$scope.linkInstagram = function() {
$cordovaOauth.instagram('######', [], {})
.then(function(result) {
console.log("Response Object -> " + JSON.stringify(result));
console.log(result.access_token);
// save the access token & get user info
AuthService.setInstagramAccessToken(result.access_token).then(function() {
console.log('Token saved!');
});
}, function(error) {
console.log("Error -> " + error);
});
}
$scope.unlinkInstagram = function() {
AuthService.removeInstagramInfo().then(function() {
console.log('Insta unlinked');
console.log(AuthService.user.attributes);
});
}
});
Service
var app = angular.module('myApp.services.authentication', []);
app.service('AuthService', function ($q, $http, $ionicPopup) {
var self = {
user: Parse.User.current(),
'setInstagramAccessToken': function(token) {
var d = $q.defer();
var user = self.user;
user.set("instagram_access_token", token);
user.save(null, {
success: function(user) {
self.user = Parse.User.current();
d.resolve(self.user);
},
error: function(user, error) {
$ionicPopup.alert({
title: "Save Error",
subTitle: error.message
});
d.reject(error);
}
});
self.setInstagramUserInfo(token);
return d.promise;
},
'setInstagramUserInfo': function(token) {
var d = $q.defer();
var endpoint = 'https://api.instagram.com/v1/users/self?access_token=' + token + '&callback=JSON_CALLBACK';
$http.jsonp(endpoint).then(function(response) {
console.log(response.data.data.username);
console.log(response.data.data.id);
var user = self.user;
user.set('is_instagram_linked', true);
user.set('instagram_username', response.data.data.username);
user.set('instagram_user_id', response.data.data.id);
user.save(null, {
success: function(user) {
self.user = Parse.User.current();
d.resolve(self.user);
},
error: function(user, error) {
$ionicPopup.alert({
title: "Save Error",
subTitle: error.message
});
d.reject(error);
}
});
});
},
'removeInstagramInfo': function() {
var d = $q.defer();
var user = self.user;
user.set('is_instagram_linked', false);
user.set('instagram_access_token', null);
user.set('instagram_username', null);
user.set('instagram_user_id', null);
user.save(null, {
success: function(user) {
self.user = Parse.User.current();
d.resolve(self.user);
},
error: function(user, error) {
$ionicPopup.alert({
title: "Save Error",
subTitle: error.message
});
d.reject(error);
}
});
return d.promise;
}
};
return self;
});
I tried something like this at the end of the function but get an error saying Error: [$rootScope:inprog] $digest already in progress
$scope.$apply(function () {
$scope.isInstagramLinked = false;
});
I'm guessing that you're assuming that the following line
$scope.isInstagramLinked = AuthService.user.attributes.is_instagram_linked;
is going to make '$scope.isInstagramLinked' update anytime 'AuthService.user.attributes.is_instagram_linked' updates. That's not the case, though. Because 'AuthService.user.attributes.is_instagram_linked' references a primitive (boolean) value, it just assigns it - it doesn't maintain any kind of reference to it - that only happens with objects.
You need to manually set $scope.isInstangramLinked = true in the $cordovaOauth.instagram() success/"then" handler.
tl;dr:
$scope.isLinked = false;
someFunction().then(function(){
$scope.isLinked = true; // this is what you're missing
})
.error(function(err){...})
If you don't want to set it manually, you can also use $scope.$watch to watch 'AuthService.user.attributes.is_instagram_linked' for changes, and then update '$scope.isInstagramLinked' when it does.
I've node on server and Angular on client...
angular routes:
var todoApp = angular.module('todoApp', ['ngResource', 'ngRoute', 'ngCookies'])
.config(function ($routeProvider, $locationProvider) {
$routeProvider.when('/', {
templateUrl: 'templates/index.html'
});
$routeProvider.when('/todo',
{
templateUrl: 'templates/todo.html',
controller:"TodoController"
});
$routeProvider.when('/admin',
{
templateUrl: 'templates/admin.html'
});
$routeProvider.otherwise({redirectTo: '/'});
$locationProvider.html5Mode(true);
});
on server side I've defined a route for '/todo'
app.use('/todo', todo);
and My todo File is
var express = require('express'),
router = express.Router(),
todo = require('../controllers/todo'),
winston = require('../../server/config/winston');
// GET users listing.
router.get('/', todo.list);
router.post('/:id', todo.save);
router.delete('/:id', todo.delete);
module.exports = router;
My Problem
if I go to home page it works fine and data shows along with loaded Pages i.e if I Enter localhost/3000/ then by default it redirects to /todo and works perfectly.
If i enter localhost/3000/todo then i only see plain text on page that is data returned from server rather then HTML page that i can see above.
I don't know whats wrong with it...
Edit
My Todo Controller
var db = require('../config/sequelize'),
StandardError = require('standard-error');
var winston = require('winston');
exports.save = function (req, res) {
if (!req.user) {
return res.send("Please Login");
}
console.log("in create", req.body);
var _task = {
task: req.body.task,
UserId: req.user.id
}
console.log(req.user);
db.Todo.create(_task).then(function (todo) {
if (!todo) {
return res.send(new StandardError('Cannot insert'));
} else {
console.log(req.body);
return res.send(todo);
}
}).catch(function (err) {
return res.send({
errors: err,
status: 500
});
});
};
exports.list = function (req, res) {
if (!req.user || req.user.isAdmin) {
return res.redirect('/');
}
console.log(db.User);
db.Todo.findAll({where: {UserId: req.user.id}}).then(function (todo) {
console.log(todo);
res.jsonp(todo);
}).catch(function (err) {
console.log(err)
res.send([{task: "No Data"}]);
});
};
exports.delete = function (req, res) {
db.Todo.destroy({
where: {
id: req.params.id,
UserId: req.user.id
}
}).then(function (response) {
console.log("deleted");
res.send(response + " Record Deleted");
//db.Todo.findAll().then(function (todo) {
// res.jsonp(todo);
// }).catch(function (err) {
// return res.render('error', {
// error: err,
// status: 500
// });
// });
});
};
May be you are confused with the angular routes and the server routes.
Use localhost/#!/todo for your todo template and localhost/todo for invoking server