Real time with AngularJs & Yii2 - angularjs

I'm developing a Yii2 REST API, with AngularJS for the frontend to consume.
I need a way to implement real time approach, e.g. for a chat, or to make some real time notifications.
Is this possible, how to achieve? I been reading about Ratchet, Socket.io and some other things, but I couldn't figure out how to make them fit together for REST or if this is the way to go.
Any advice would be appreciate.

You have a few options here.
Short / Long Polling (use setTimeout)
app.controller("MyController", function($scope, $timeout, $http) {
$scope.messages = [];
$timeout(callAtTimeout, 3000);
function callAtTimeout() {
console.log("Timeout occurred");
$http.get('PATH TO RESOURCE TO GET NEW MESSAGES').then(
function(res) { // update $scope.messages etc... },
function(err) { // handle error }
);
}
});
For both short and long polling on client side, you send request, wait to get a response back, then wait 3 seconds and fire again.
Short/Long polling works differently on the server side. Short polling will just return a response immediately - whether something has changed or not. Long polling, you hold the connection open and when there is a change, then you return the data. Beware of keeping too many connections open.
Socket.io (websockets)
I would recommend that you implement websockets using either something like node.js on your own web server or a hosted solution like Firebase.
The thing with Firebase is that from PHP, you can send a post request to a REST endpoint on the firebase server. Your javascript can connect to that endpoint and listen for changes and update the dom accordingly. It is possibly the simplest of all to implement.
I personally wouldnt use PHP for socket programming but it can be done.

To have real-time updates on your website, you can implement one of the following approaches depending on your requirement and how fast you need to update your frontend component.
Using a websocket
You can use a library like https://github.com/consik/yii2-websocket to implement it with Yii2. But this will act as a separate service from your REST API. Therefore you have to make sure that proper security practices are applied.
Running an Angular function with a timeout
You can continuously poll an endpoint of the REST API with a timeout of few milliseconds to receive updated values.
The second approach will create many requests to the API which will increase the server load. Therefore my preferred approach is using a websocket.

Related

How to track a service whose response is keep changing after a minute in angular JS?

I am working with angular js (1.x).
I need to display some data which is coming from backend. For that I am calling a service.
Problem is that the response keep changing periodically. But still I didnt use setTimeInterval as this may overload backend due to continuously sending request from UI. So I let user to manually refresh the page to update the data.
Is there any way in which I can auto-update the data without having to use setTimeInterval?
What is a websocket?
WebSockets is an advanced technology that makes it possible to open an interactive communication session between the user's browser and a server. With this API, you can send messages to a server and receive event-driven responses without having to poll the server for a reply.
Src: https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API
AngularJs + Websockets
You can use ng-websocket for angularjs
https://github.com/wilk/ng-websocket
or
AngularJS WebSocket Service Example

Detecting when a user's click goes to the server and when it does not in AngularJS web app

Is there a way to detect when a user's click somewhere in our web app accesses to the server and when it does not? We need this knowledge for a simple keep alive mechanism we want to add to the app. I have already implemented the functionality to detect user clicks anywahere in page, using help from this post: Click everywhere but here event. And now we need to add functionality to detect when the click causes an access to server and when it doesn't (because we use two timers in our keep alive, one for server session and one for client session).
The backend is implemented in ASP.NET Core Web API.
Thanks,
ashilon
The least invasive solution I can think of would be to add a request or response interceptor to the $http service that would track the time of the last event. It might look something like this, but obviously would have to be modified for the particulars of your angularjs app.
angular.module('yourAppName').
service('SessionInterceptor',
['$q', '$rootScope',
function($q, $rootScope) {
'use strict';
return {
response: function(response) {
$rootScope.lastServerActivity = response.headers().date;
return response;
},
responseError: function(rejection) {
$rootScope.lastServerActivity = rejection.headers().date;
return $q.reject(rejection);
}
};
}]);
Then you can use the lastServerActivity to calculate an idle time on their next click or via a timer and kill the session if appropriate. You could just as easily implement the request side rather than the response side. You could also use javascript to get the date rather than from the http headers. Whatever you choose will be influenced by how you are doing the client side session timeouts.

Update scope properties when server data changes without client checking server angularjs

For this method call:
$http.get("Some api call").then(function (response) {
$scope.data=response.data;
});
Suppose the response keeps on updating from time to time and I wish to update the $scope.data property whenever the response is updating without firing the $http.get using timeout or interval methods.
I am not getting any solution for this issue. Please provide your ideas with examples.
What you are asking is called Polling.
Your HTTP request will NOT get the latest data unless you fire the request again. Unless you fire the request again, your response will not have the latest data and thus, your data object will also not get updated.
No amount of $watch will suffice. Simply because, unless you poll the server periodically, you will not get the latest data.
This is how HTTP/1.1 behaves. This is soon about to change with HTTP/2
If you do not wish to make periodic requests, then have a look at sockets. You have not mentioned your backend but a Nodejs example can be found at socket.io.

Preventing similar POST requests with AngularJS

I am currently building a dashboard page with multiple widgets. Those widgets retrieve their data with REST calls ($resource). A few widgets make similar calls and I don't want to DDOS our server so I am looking for a way to make a call only once and resolve all similar requests with the same response.
Since I am restricted to using POST requests only, I cannot use the cache option that $resource offers. This seems to be doing exactly what I want but only for GET requests.
I was thinking along the lines of using a http interceptor to queue similar POST requests, fire only one of them and resolving them all when the first one gets its response.
However, I cannot seem to put the pieces together so any help is appreciated. I am open to other options.
Kind regards,
Tim
Services in AngularJS are singletons, so a solution would be to store the response in the service, as a variable. Then next time you'll do the request, previously check if the variable is null, if it's not you wrap it in a promise and returned it. If it's null, then you do the request, and store the response for the next call.
You can also either use this in your request service or in your interceptor service.
I hope I helped !
Refactor your widgets to depend on a service (singleton).
This service should either poll the server via XHR, or get server push via websocket for updates.
If polling, look into server side caching and etags.

How do I fully intercept AND requeue http requests using dojo

I am down to a choice between angularjs and dojo as my front end MV* framework. One particular functionality which in my mind is critical is the ability to do unobtrusive and transparent authentication. I was extremely impressed with angular's capability in this regard using http interceptors. See http://www.espeo.pl/2012/02/26/authentication-in-angularjs-application for a good sample implementation/explanation.
It allows one to queue up any and all 401 responses while waiting for successful login and then re-transmit them once login is successful by using a combination of broadcast events, event handling, and http interceptor (plus a request queue). The overhead on each request appears to be minimal.
I wanted to compare the ability of dojo to do the same, but from my examination it does not appear to be possible. Examining the dojo documentation, it appears that this would probably have been possible in dojo 1.4 using the ioPipline, but that that is deprecated in favor of dojo/request/notify which does not appear to provide as low-level of an interception (specifically it doesn't appear to give access to the request object when an error is received). it is also not clear if it is possible to modify or replace the response from within the notified function...
Can anyone point me to a clear example of this having been accomplished using dojo's request/notify service or an alternate methodology using dojo? Critical requirements are that the authentication be transparent to the protected functions/controllers/objects (they should simply receive a promise which is eventually fulfilled), that the authentication code be able to be centralized (it should not require modification to every object/event/etc that makes a request), and that it should be secure (in the sense that both authentication/authorization should happen on the server side and no javascript manipulation should be able to bypass that requirement)...
You can register handlers within dojo/request/registry to intercept and handle requests made using dojo/request any way you want. Here’s a modified (untested, probably slightly defective) example based on the reference guide:
require([ "dojo/request/registry", "dojo/request/xhr" ], function (registry, xhr) {
request.register(function (url, options) {
return xhr(url, options).response.then(function (response) {
if (response.status === 401) {
// retry later
}
return response;
});
}, true);
});
With the above example, any request made with dojo/request will be intercepted and the method provided will be called. If you wanted to conditionally only match certain requests with this handler, you can pass another tester function as the first argument. This is detailed in the reference guide linked above.
All your handler function then needs to do is return a promise that will eventually resolve to the expected data.

Resources