IONIC not receiving Socket data from server - angularjs

I am using ionic framework for my android app and MEANJS on my server. I am using Web Sockets to get realtime data. While the server side web application updates automatically every time a CRUD happens in the android application, the android app does not update automatically when a change is made on the server side.
Android App Service(AngularJS)
.service('Socket', ['Authentication', '$state', '$timeout',
function (Authentication, $state, $timeout) {
// Connect to Socket.io server
this.connect = function () {
// Connect only when authenticated
if (Authentication.user) {
this.socket = io('https://cryptic-savannah-60962.herokuapp.com');
}
};
this.connect();
// Wrap the Socket.io 'on' method
this.on = function (eventName, callback) {
if (this.socket) {
this.socket.on(eventName, function (data) {
$timeout(function () {
callback(data);
});
});
}
};
// Wrap the Socket.io 'emit' method
this.emit = function (eventName, data) {
if (this.socket) {
this.socket.emit(eventName, data);
}
};
// Wrap the Socket.io 'removeListener' method
this.removeListener = function (eventName) {
if (this.socket) {
this.socket.removeListener(eventName);
}
};
}
Client Side Controller
if (!Socket.socket && Authentication.user) {
Socket.connect();
}
Socket.on('orderCreateError', function (response) {
$scope.error = response.message;
});
Socket.on('orderCreateSuccess', function (response) {
if ($scope.orders) {
$scope.orders.unshift(response.data);
}
});
Socket.on('orderUpdateSuccess', function (response) {
if ($scope.orders) {
// not the most elegant way to reload the data, but hey :)
$scope.orders = Orders.query();
}
});
Server Controller(NodeJS)
socket.on('orderUpdate', function (data) {
var user = socket.request.user;
// Find the Order to update
Order.findById(data._id).populate('user', 'displayName').exec(function (err, order) {
if (err) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: errorHandler.getErrorMessage(err) });
} else if (!order) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: 'No order with that identifier has been found' });
} else {
order.name = data.name;
order.phone = data.phone;
order.water = data.water;
order.waiter = data.waiter;
order.napkin = data.napkin;
order.complete = data.complete;
order.rating = data.rating;
order.payment_mode = data.payment_mode;
order.order_source = data.order_source;
order.orderfood = data.orderfood;
order.save(function (err) {
if (err) {
// Emit an error response event
io.sockets.emit('orderUpdateError', { data: data, message: errorHandler.getErrorMessage(err) });
} else {
// Emit a success response event
io.sockets.emit('orderUpdateSuccess', { data: order, updatedBy: user.displayName, updatedAt: new Date(Date.now()).toLocaleString(), message: 'Updated' });
}
});
}
});
});

You have two emit channels on your server side but neither event is handled on the client side.
Per socket.io docs, you need something like:
socket.on('orderUpdateSuccess', function (data) {
// do something inside the app that will update the view
console.log(data);
Orders.update(data); // assuming you have a service called Orders to keep track of live data -- don't forget [$scope.$apply][2]
});
Using your example code
Socket.on('orderUpdateSuccess', function (response) {
if ($scope.orders) {
$scope.$apply(function() {
// not the most elegant way to reload the data, but hey :)
$scope.orders = Orders.query();
});
}
});

Related

Socket.io - angular.js. - always disconnected with "ping timeout"

Trying to connect with Angular js + socket.io to the server (Node.js - nestsJS)
I have both React and Angular app
in react app everything is work
in Angularjs I got always "ping timeout" and then it try to recconect - on the server I saw the connection and it pass the authentication flow.
when I going to the network tab(WS) I got my events after authenticated in the backend so it looks like its a client issue
so every ~30sec the console output disconnect + reason "ping timeout"
Angular code -socket service
.factory('socket', socket);
socket.$inject = ["$rootScope"];
function socket($rootScope) {
const options = {
transports:['websocket'],
// allowUpgrades: false,
query: {
token : "token",
},
forceNew: true
}
var socket = io.connect('/', { ...options, path: `/socket.io` });
return {
on: function(eventName, callback) {
socket.on(eventName, function() {
var args = arguments;
$rootScope.$apply(function() {
callback.apply(socket, args);
});
});
},
emit: function(eventName, data, callback) {
socket.emit(eventName, data, function() {
var args = arguments;
$rootScope.$apply(function() {
if (callback) {
callback.apply(socket, args);
}
});
})
}
};
controller:
socket.on('connect', function (data) {
console.log("connect")
});
socket.on('connection', function (data) {
console.log("connect")
});
socket.on('disconnect', function (data) {
console.log("disconnect")
console.log(data)
});
socket.on('events-test', function (data) {
console.log("test")
console.log(data)
})
in the network tab i can see the "events-test" events and it will create a new "ws" tab evrey reconnection
Solved by change the socket-io client version to 2.3.0
Use socketio version 2 on the client side to match the server. 3 and 4 are incompatible with server v2

Save and display comment in real-time using angularjs and socket.io

I have problem with socket.io. In my code router.post(/comment,...) saving user comments in database (using mongoose) and I am trying emit this save. In controller function readMoreCourse is to get and display all comments from database (and question how use socket to this function that using ng-reapat display comment in real-time). Function AddComment is on client side chceck valid form and next post comment to database.
My question: How in real-time save and display user comment using angular (ng-repeat?) and socket.io? Honestly I making this first time, and I have short time, thanks for any help.
Server
io.on('connection', function(socket){
socket.emit('comment', function(){
console.log('Comment emitted')
})
socket.on('disconnect', function(){
})
})
API
router.post('/comment', function(req, res) {
Product.findOne({ _id: req.body._id }, function(err, product){
if(err) {
res.json({ success:false, message: 'Course not found' })
} else {
User.findOne({ username: req.decoded.username }, function(err, user){
if(err){
res.json({ success:false, message: 'Error'})
} else {
product.comments.push({
body: req.body.comment,
author: user.username,
date: new Date(),
});
product.save(function(err){
if(err) throw err
res.json({ success: true, message: 'Comment added })
**io.emit('comment', msg);**
})
}
})
}
})
})
controller
Socket.connect();
User.readMoreCourse($routeParams.id).then(function(data){
if(data.data.success){
app.comments = data.data.product.comments;
} else {
$window.location.assign('/404');
}
});
app.AddComment = function(comment, valid) {
if(valid){
var userComment = {};
userComment.comment = app.comment;
Socket.on('comment', User.postComment(userComment).then(function(data){
if(data.data.success){
$timeout(function(){
$scope.seeMore.comment = '';
},2000)
} else {
app.errorMsg = data.data.message;
}
}));
} else {
app.errorMsg = 'Error';
}
}
$scope.$on('$locationChangeStart', function(event){
Socket.disconnect(true);
})
factory
userFactory.readMoreCourse = function(id) {
return $http.get('/api/seeMore/' + id)
}
userFactory.postComment = function(comment){
return $http.post('/api/comment', comment);
}
.factory('Socket', function(socketFactory){
return socketFactory()
})
In your socket factory, initialize socket.io emit and on events.
app.factory('socket', ['$rootScope', function($rootScope) {
var socket = io.connect();
return {
on: function(eventName, callback){
socket.on(eventName, callback);
},
emit: function(eventName, data) {
socket.emit(eventName, data);
}
};
}]);
and call this from controller
app.controller('yourController', function($scope, socket) {
User.postComment(userComment).then(function(data){
if(data.data.success){
$timeout(function(){
$scope.seeMore.comment = '';
},2000);
// Emit new comment to socket.io server
socket.emit("new comment", userComment);
} else {
app.errorMsg = data.data.message;
}
});
// other clients will listen to new events here
socket.on('newComment', function(data) {
console.log(data);
// push the data.comments to your $scope.comments
});
from socket.io server
io.on('connection', function(socket) {
// listen for new comments from controller and emit it to other clients
socket.on('new comment', function(data) {
io.emit('newComment', {
comment: data
});
});
});
EDIT:
If you just want to push from server side,
io.on('connection', function(socket) {
// after saving your comment to database emit it to all clients
io.emit('newComment', {
comment: data
});
});
and remove this emit code from controller:
socket.emit("new comment", userComment);
But this method can be tricky because the user who posts the comment should immediately see the comment added to the post. If you let socket.io to handle this there will be a few seconds lag for the guy who posted the comment.

CordovaHttp and Angular Post - no response

I'm using CordovaHTTP with Angular and injected the Cordova HTTP into a service. I haven't found many examples on how to implement a POST so below is what I did so far. The issue I'm having is that the post block never reaches the success or error blocks and my debug statements are not getting printed.
Does this look correct?
Calling function:
this.authenticate = function ( code, data, callback ) {
try {
// Build url
var url = o.buildServerUrl(o.loginUrl, code);
RestService.post(url, data, function(response) {
if (response.status === o.HTTP_STATUS_OK) {
...
}
callback(response);
});
}
catch(err) {
var response = o.createServerErrorResponse(o.MSG_SERVER_ERROR);
callback(response);
}
}
Service:
oApp.service( 'RestService', function( cordovaHTTP ) {
this.post = function ( url, data, callback ) {
try {
// Build url
if (o.debug) console.log('Cordova REST: '+url);
cordovaHTTP.post( url, data, {}, function(response) {
if (o.debug) console.log('Rest ok');
// Success
var response = o.processServerResponse(response);
callback(response);
}, function(response) {
if (o.debug) console.log('Response error');
var response = o.processCordovaServerResponse(response);
callback(response);
});
}
catch(err) {
var response = o.createExceptionResponse(err.message);
callback(response);
}
}
});

How do I validate a recaptcha in node without a challenge field?

The latest version of recaptcha no longer expects a challenge field, the angular-recaptcha directive is up to date with these changes, but none of the node recaptcha libraries work without a challenge field.
How do I validate a recaptcha in node without a challenge field?
function verifyRecaptcha(key, callback) {
https.get("https://www.google.com/recaptcha/api/siteverify?secret=" + recaptcha_vars.privateKey + "&response=" + key, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk.toString();
});
res.on('end', function() {
try {
var parsedData = JSON.parse(data);
console.log(parsedData);
callback(parsedData.success);
} catch (e) {
callback(false);
}
});
});
}
exports.captcha = function(req, res) {
verifyRecaptcha(req.body.response, function(success) {
if (success) {
res.json({ success: true });
// TODO: do registration using params in req.body
} else {
res.json({ success: success, error: "Captcha failed"});
// TODO: take them back to the previous page
// and for the love of everyone, restore their inputs
}
});
};

Cant listen for server events using publishUpdate with sails js

Im trying to publishUpdate some data from the server in order to listen for user/profile creation but im not able to listen to those events in the client using Angular. Is it possible im missing something here? Or maybe something wrong im doing?
// UserController
saveUser: function(req, res) {
User.create({name: req.param('name'), profile: {aboutMe: req.param('about'), gender: req.param('gender')}})
.exec(function(err, user) {
Profile
.findOneById(user.profile)
.exec(function(err, profile) {
profile.user = user.id;
profile.save(function(error, saved){
if (error) return res.badRequest('Error.');
if (saved) res.json(saved);
Profile.publishUpdate(saved.id, saved);
});
});
});
}
// Client Angular
$scope.send = createUser;
listenProfile();
function createUser() {
var obj = {
name: $scope.name,
about: $scope.profile.about,
gender: $scope.profile.gender
User.create(obj).then(function(data) {
console.log(data); // Data displayed correctly
}, function(error) {
console.log(error);
});
}
function listenProfile() {
io.socket.on('profile',function(data){
console.log(data); //Nothing happens?
});
};
Try changing it to a capital P:
function listenProfile() {
io.socket.on('Profile',function(data){
console.log(data); //Nothing happens?
});
};
I think that are missing "suscribe" to your model... for example
Profile.subscribe(req.socket, data);
And linked to your app via GET.
io.socket.get("/profile",function(data){
console.log(data);
});

Resources