I need to update my mongodb using nodejs and angularjs on the front end. I have the below code but i get error like `TypeError: Cannot read property 'put' of undefined
My angularjs controller :
myApp.controller('userController', ['$scope', '$resource', 'AuthService','iden','$http', function ($scope, $resource, AuthService,iden,$http) {
console.log(usersOnline);
var Meetup = $resource('/api/user', {},{
query: {method: 'get', isArray: true}
});
$scope.users = [];
$scope.userss = [];
$scope.text='mikyas';
Meetup.query({text: usersOnline}).$promise.then(function (results) {
$scope.users = results;
}, function(error) {
// console.log(error);
$scope.meetups = [];
});
console.log(usersOnline);
function getUser(iden,$http) {
//return promise here
var Users = $resource('/api/users', {},{
query: {method: 'get', isArray: true}
});
$scope.usersOnline='a';
return Users.query({username: usersOnline}).$promise
//other code as is
}
$scope.id='cpasgrave';
$scope.lol=getUser();
$scope.lol.then(function(user,$http){
console.log(user[0]._id);
iden=user[0]._id;
$scope.userss = user;
console.log(iden);
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
console.log(iden);
}]);
And my api on the server side :
*
module.exports.updateUser = function (req, res) {
var id = req.body.id;
User.findById(id, function(err, user) {
if (err) throw err;
// change the users location
user.auto = 'true';
// save the user
user.save(function(err) {
if (err) throw err;
console.log('User successfully updated!');
});
});
}
`
Remove the $http argument in your $scope.lol.then(function(user,$http) function.
$scope.lol.then(function(user){
console.log(user[0]._id);
iden=user[0]._id;
$scope.userss = user;
console.log(iden);
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
Also, if you define getUser (iden, $http), make sure you put correct arguments when you call it...
$scope.id='cpasgrave';
$scope.lol=getUser(iden, $http);
try replacing this:
$http.put('/api/updateUser' + user[0]._id, user[0]);
});
with this:
$http({
method: 'PUT',
url: '/api/updateUser' + user[0]._id, user[0]
}).then(function successCallback(response) {
console.log('put success');
}, function errorCallback(response) {
console.log('put failed');
});
Related
I am implementing YouTube Search API in my Website, when I am calling the api from my route the results are returned but the page is rendered while the results are being computed, I guess because of the asynchronous behavior.
My route through which I am calling the API:
router.get('/video/results/:search_query', middleware.ensureAuthenticated, function (req, res) {
query = req.params.search_query;
console.log(query);
var dataFinal;
var resp = youtube.search.list({
part: 'snippet',
q: query,
type: 'video'
},function (err, data, response) {
if (err) {
console.error('Error: ' + err);
res.json({
status: "error"
});
}
if (data) {
// console.log(typeof data);
dataFinal = data;
// return res.json({
// status: "ok",
// data: data
// });
console.log(data);
//res.render('resultsVideo',{results:data})
}
});
res.render('resultsVideo',{data:dataFinal})
});
Please tell me how can I call the API and use the results in my EJS file to display.
you can use function callback to get the desired result.
router.get('/video/results/:search_query', middleware.ensureAuthenticated, function (req, res) {
query = req.params.search_query;
console.log(query);
var dataFinal;
function resp() = youtube.search.list({
part: 'snippet',
q: query,
type: 'video'
},function (err, data, response) {
if (err) {
console.error('Error: ' + err);
res.json({
status: "error"
});
}
if (data) {
// console.log(typeof data);
return data;
// return res.json({
// status: "ok",
// data: data
// });
console.log(data);
//res.render('resultsVideo',{results:data})
}
});
res.render('resultsVideo',{data:resp()})
});
I have created login page and trying to do client-side authentication. I know it's a bad practice, but I want to learn it. I am accessing the data using JSON server. When I submit the button , my data is getting posted in the server, but I am failing when I am trying to match the content on success call. Please let me know what I am doing wrong.
Any help / advice would be greatly appreciated.
AngularJS :
app.factory('Authentication', function($http, $q, session) {
var service = {};
service.isAuthenticated = function() {
return isAuthenticated = false,
username = ""
};
service.login = function(username, password) {
return $q(function(resolve, reject) {
$http.post('http://localhost:3000/loginfo', {
username,
password
})
.then(
function successCallback(response) {
var data = response.data;
var user = {};
for (var i = 0; i < data; i++) {
alert('go');
if (data[i].username === username && data[i].password === password) {
user = data[i];
break;
}
}
session.create(response.data.id, response.data.username);
resolve(response.data);
console.log(response.data)
},
function(err) {
reject(err);
});
});
};
return service;
});
/* client-side */
app.controller('credientials', function($scope, $http, auth) {
$scope.userCred = {
username: '',
password: ''
};
/*-----Form Submition-----*/
$scope.log = function(userCred) {
$scope.isAuthenticated = true;
Authentication.login(userCred.username, userCred.password)
.then(function(result) {
console.log(result);
}, function(err) {
console.error(err);
});
};
}]);
Here is a snippet from my express.js file:
function playlistTracks(req, res) {
var tracks = [];
var genres = ['hi'];
var playlistOption = {
url: 'https://api.spotify.com/v1/users/' + req.params.user + '/playlists/'+ req.params.id + '/tracks',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
rp(playlistOption)
.then(function (body) {
tracks = body;
return tracks;
})
.then(function (tracks) {
getGenre(tracks);
res.render('tracks', {
data: tracks
});
})
.catch(function (err) {
console.log('couldnt get tracks' , err);
throw err;
});
function getGenre(tracks) {
tracks.items.forEach(function(e){
var reqGenre = {
url: 'https://api.spotify.com/v1/artists/' + e.track.album.artists[0].id,
json: true
};
rp(reqGenre)
.then(function(body) {
genres.push(body.genres)
})
.catch(function(err){
console.log('couldnt get genres' , err);
throw err
});
});
io.emit('playlists', {genres: genres});
console.log(genres) // <---empty
}
}
the "getGenre" function is where I have the most trouble with. I want to know how I can update the "genres" array with that function. I've tried a couple of solutions but can't seem to get my head around the async nature of a request.
I've looked at this and other solutions already, but can't figure out how to apply them to my code.
I'm using request-promise to get the api request.
getGenre fetches data async, so you can try such code:
function playlistTracks(req, res) {
var tracks = [];
var playlistOption = {
url: 'https://api.spotify.com/v1/users/' + req.params.user + '/playlists/'+ req.params.id + '/tracks',
headers: { 'Authorization': 'Bearer ' + access_token },
json: true
};
rp(playlistOption)
.then(function (body) {
tracks = body;
return tracks;
})
.then(function (tracks) {
getGenre(tracks);
res.render('tracks', {
data: tracks
});
})
.catch(function (err) {
console.log('couldnt get tracks' , err);
throw err;
});
function getGenre(tracks) {
var promises = tracks.items.map(function(e){
var reqGenre = {
url: 'https://api.spotify.com/v1/artists/' + e.track.album.artists[0].id,
json: true
};
return rp(reqGenre)
.then(function(body) {
return body.genres
})
.catch(function(err){
console.log('couldnt get genres' , err);
throw err
});
});
return Promise.all(promises).then(function(results) {
var genres = ['hi'].concat(results);
io.emit('playlists', {genres: genres});
console.log(genres)
});
}
}
Trying to access $scope.mySlot.id but it is undefined.
$scope.removeMe = function() {
var shouldRemove = confirm('Remove you from this field trip?');
if (shouldRemove) {
var data = null;
UserService.me().then(function(me){
var data = {userID: me.id, eventID: tripID}
console.log(data);
return data;
}).then (function(data){
var mySlot = GreenTripFilledSlotsFactory.get(data);
return mySlot;
}).then (function(mySlot) {
$scope.mySlot = mySlot;
console.log("this is $scope.mySlot: ");
console.log($scope.mySlot); //this shows up as a resource with proper values
console.log("this is $scope.mySlot.id: ")
console.log($scope.mySlot.id); //this is undefined
}).then (function(success){
return $scope.mySlot.$delete(); // this isn't working'
}).then(function(success){
console.log('mySlot deleted');
route.reload();
}).catch(function(error){
console.log(error);
})
}
};
In the console.logs $scope.mySlot is shown as a resource and it does list the values of it. But I'm confused why $scope.mySlot.id is undefined.
FACTORIES:
.factory('GreenTripSlotsFactory', ['$resource', function($resource) {
return $resource('/api/GreenTripSlots/:id/', {id: '#id' }, {
update: {method: 'PUT' }
});
}])
.factory('GreenTripFilledSlotsFactory', ['$resource',
function($resource) {
return $resource('/api/GreenTripSlots/:userID/:eventID/:slotID',
{id: '#id' }, {
update: {method: 'PUT' }
});
}])
BACKEND contollers:
// = /api/GreenTripSlots/:userID/:eventID
router.route('/:userID/:eventID')
.get(function(req,res) {
procedures.procGetSlotByUserAndTrip(req.params.userID,
req.params.eventID).then(function(greenTripUserSlot){
res.send(greenTripUserSlot);
}, function(err) {
console.log(err);
res.sendStatus(500);
})
})
// = /api/GreenTripSlots:/userID/:eventID/:slotID
router.route('/:userID/:eventID/:slotID')
.get(function(req,res) {
procedures.procGetSlotByUserAndTrip(req.params.userID,
req.params.eventID).then(function(greenTripUserSlot){
res.send(greenTripUserSlot);
}, function(err) {
console.log(err);
res.sendStatus(500);
})
})
.delete(function(req, res){
procedures.procRemoveMe(req.params.slotID).then(function(){
res.sendStatus(204);
}, function(err) {
console.log(err);
res.sendStatus(500);
});
})
Backend Procedures:
exports.procGetSlotByUserAndTrip = function(userID, eventID) {
return db.fnRow('procGetSlotByUserAndTrip', [userID, eventID])
}
exports.procRemoveMe = function(slotID) {
return db.fnEmpty('procRemoveMe', [slotID])
SQL Stored Procedure for Get:
CREATE DEFINER=`CharleyHannah`#`localhost` PROCEDURE
`procGetSlotByUserAndTrip`(pUserId INT, pEventId INT)
BEGIN
SELECT *
FROM userEvents u
WHERE u.userID = pUserId & u.eventID = pEventId;
END
SQL Stored Procedure for delete:
CREATE DEFINER=`CharleyHannah`#`localhost` PROCEDURE
`procRemoveMe`(pSlotId int)
BEGIN
DELETE
FROM userEvents
WHERE id = pSlotId;
END
Your function GreenTripFilledSlotsFactory.get(data); returns a promise. You can write something like that:
var _promise = GreenTripFilledSlotsFactory.get(data);
_promise.then(function(res) {
$scope.mySlot = res;
console.log($scope.mySlot.id); //should display your value now
});
In the res Variable your object is stored.
You assign userToRemove outside the promise then and it's executed before $scope.ME assingning.
Instead of using the factories, I had success in just using $http.get and $http.delete requests:
$scope.removeMe = function() {
var shouldRemove = confirm('Remove you from this field trip?');
if (shouldRemove) {
var data = null;
UserService.me().then(function(me){
var data = {eventID: tripID, userID: me.id}
console.log(data);
return data;
}).then (function(data){
var mySlot = $http.get('/api/GreenTripSlots/' + data.eventID + '/' + data.userID);
console.log(mySlot);
return mySlot;
}).then (function(mySlot) {
var slotToDelete = mySlot.data;
console.log(slotToDelete);
console.log(slotToDelete.id)
return slotToDelete;
}).then (function(slotToDelete){
var slotID = slotToDelete.id;
$http.delete('/api/GreenTripSlots/delete/' + slotID);
console.log('deleted successfully')
$route.reload();
}).catch(function(error){
console.log(error);
})
}
};
}])
I have a JSON source and want to get results from it with a post request.
When I test with POSTMAN extension in chorme it works really well. But when I do that with angularJS the page keep loading and chrome consoles shows errors.
My code is here:
angular.module('loginApp', []).controller('loginController', function ($scope, $http) {
$scope.userName = '';
$scope.userPass = '';
$scope.output = function () {
var params = JSON.stringify({
username: '******',
password: '******'
});
$http({url: "http://xx.xx.xx.xx/api/user/login.json",
method: 'POST',
data: params,
headers: {
'Content-Type': 'application/json',
'Accept': 'application/json'
}
}).then(function (response) {
return response;
});
};
});
Any help would be appreciated :)
try this, and after post error if occured:
var LoginApp = angular.module('loginApp', []);
LoginApp.controller('loginController', function ($scope, $common) {
$scope.userName = '';
$scope.userPass = '';
$scope.output = function () {
var params = JSON.stringify({
username: '******',
password: '******'
});
$common.ajax("http://xx.xx.xx.xx/api/user/login.json", params, "POST").then(function (response) {
console.log(response);
return response;
});
};
});
LoginApp.factory("$common", function($http, $q) {
function ajax(url, param, method) {
var request = $http({
method: method,
url: url,
data:param
});
var promise = request.then(
function(response) {
return(response.data);
},
function(response) {
console.log("Ocurred error: " + response);
return($q.reject("Something went wrong"));
}
);
return promise;
}
return({
ajax:ajax
});
});
Try this:
$scope.output = function () {
var params = {
username: '******',
password: '******'
};
$http.post("http://xx.xx.xx.xx/api/user/login.json", params)
.then(function (response) {
return response;
});
};
Also you should move your http request to a service. It's a bad practice put it in a controller.