How to change scope variable when push notification received - javascript

I have a notification icon in my web app that shows the number of notifications. The front end of the application is made using angularjs.
The count for the icon is stored in a $rootScope variable. I want to increment the variable(or call a web service that returns count) when a push notification is received.
The serviceworker.js file does not have access to the scope variables in angularjs. How do I change the count variable's value from the serviceworker.
I thought of adding a change event listener on localStorage item.
On logging in, I will create a item.
localStorage.setItem('notifCount', 0);
When I receive a push notification, I will increment notifCount in localStorage in serviceworker.js and the change event will fire. I could add the localStorage change listener in one of controller files and call a web service or just increment the $rootScope variable.
But this would happen even when someone manually changes the localStorage in dev tools.
I want to know if I can do it this way(if it's the right way) or is there a better method. I don't feel like this is the right way.

Data is sent between workers and the main thread via a system of messages — both sides send their messages using the postMessage() method, and respond to messages via the onmessage event handler (the message is contained within the Message event's data attribute.) The data is copied rather than shared.
For more information, see
MDN Web API Reference - Using Web Workers

Related

Refresh platform data in tables after action

if i did some edits on data via functions on objects in tables are still the old data.
Only after Browser refresh the changes are visible.
Data is coming via Slate JavaScript Functions from Platform.
Is there a way to refresh this data shown in widget table?
The Object Set integration in the Slate Platform tab is backed by the Object Set Service search endpoint. This endpoint in turn hits the underlying index in the Phonograph data store associated with the object type.
When you make a data change via an Action, there is a brief (normally less than 3s) delay before the changes are reflected in the index. They're immediately reflected if you access the modified object(s) by primary key.
So in Slate you can set up an Event "chain" based on the success event broadcast from the Action, through a Toast Widget with a 3-4s timer, to an event that triggers on w_toastWidget.didClose -> s_myObjectSet.run.
This should tell Slate to update the object set 4 seconds after the successful submission of the Action.
A future planned update to the Object storage infrastructure will provide a version of Actions that guarantees when the request returns successfully that the changes will already be reflected in search results.

Simple web development concept I can't find any info on +update

Let's say we have a web app that only has one element, for example an image IMG1 and if an user clicks on it, it will change to another image IMG2 (this change should be visible only to the users that clicked and triggered the event).
Then, I have another event that triggers when a total of 100 users clicked on the image (or any other back-end related event), and this time I want to dynamically change the image to IMG1 (but now I want the change to happen and be visible to all the users of the website).
The confusion starts when I realise that for both events the function would be the same (changing the src of that HTML img element) yet I want it to have a different effect:
on the event of a user click change it for that user only.
on an outside event that doesn't involve a specific user, change it for all the users to see the same image.
How does this work? what is the thing that makes the difference between a HTML change that only affects the users locally (on their actions) and a change that has a global effect (to all the users).
UPDATE !!!
I should have been more specific with what I don't know.
I'm familiar with AJAX request and I already have the backend sorted.
In the frontend script I have an event listener for the event from the backend, and all my questions are actually about 'what and how to do it' after the event listener is triggered.
Now, what I want to do when this happens is to make some changes, the main one being to change that image IMG1 to IMG2 for all the users (as it would be a dynamic update to the website) but also:
I need that change to be permanent, so in a case of users reloading the page or new users coming in, they all should still see IMG2. (And the only time the image would change would be when the event listener on the frontend script will trigger again on the same backend event to change the image again (to IMG3) for example. And yes, in this example there is NO 'on click' request for the users to change the image, so ignore my example previous to the update.
Now to address your answers, I checked the web sockets stuff and it seems to be doing what I need if I run that 'on event' change of image to all sockets. Which only leaves me with 2 questions now:
1) Will this change that occurs on all sockets to change the image be permanent, so in a case of users reloading the page or new users coming in, they will all see the new image (IMG2) as a permanent change to the webpage ?
2) Regarding these type of permanent changes, isn't reactJs a way of doing such changes dynamically?
What would actually happen if on that event listener (for the backend event) I simply ignore all the web sockets stuff and run the same code of changing the src of the image ?
2.5) Because from how I see it, that event in the backend fires without any specific user input, thus is not linked with any user. So if I simply run the code on that event without websockets It should either do absolutely nothing (so no change for anyone) OR do the change for all the users (acting simply as a dynamic update to the webpage). How does this work?
I'm looking forward for your answers, and thank you all in advance!!!
The click event needs to be handled by an AJAX request, sending a message to the server and the server will handle that and respond. Upon the response, the first type of event is executed for the user.
On server-side you will need to have an event queue somewhere, maybe in the database. If you are using WebSockets, then you will have to execute the second type of event for all users if the request is met via WebSocket channels. If you are not using WebSockets, you will need to do polling from the browser. Anyway, you will need a counter on the server-side to be able to determine when the second type of event is met.
EDIT
Yes, WebSockets are the way to go unless there is a strong reason not to do so, like a boss saying he or she does not want the server to use WebSockets. With WebSockets you have a live channel between the server and the client browsers. You can use this channel to send the URL change to the client. On the other hand, the client will have to handle the change with Javascript, gathering the tags where the src is to be changed and change them. If you happen to have a class of changable for all such tags, then executing the change can be done with a function like this:
function changeSources(newSrc) {
var items = document.getElementsByClassName("changable");
for (var index = 0; index < items.length; index++)
items[index].src = newSrc;
}
However, this change will be effectuated only for the loaded page which was initially loaded and upon new loads, this, by itself will not use the new src. So you will have to solve that problem as well. A neat way to do it is to store the new src on the server before you send it out to the client via WebSocket and use this stored src as the src of those tags when the client requests for the HTML. So, your problem has two parts, the first is changing the src on already loaded pages and the second is making the change permanent.
ReactJS is a Framework. At this point we need to define the technical background, since ReactJS will use a possible solution from these.
WebSocket
https://www.npmjs.com/package/react-websocket
This is a WebSocket implementation. The best technical background here is to use WebSockets unless there is a very good reason not to do so.
Server notification system
https://www.npmjs.com/package/react-notifications
Server notification systems in general are one-way ticket roads. The server may send a notification, but the client has no such possibility.
Polling
The browser may periodically send HTTP requests to the server and this way it can receive the src change response. This is a good solution if WebSockets and server notification systems are not an option.
Forever frame
You can use an invisible iframe to be loaded forever, which will provide you with the possibility of sending real-time messages from the server to the client, but this is very hacky.
The difference may be between a front end, running in the browser, or the mobile app, of each user, which is local, and the back end, where you can share data between all users.
This can be implemented by, for example, firebase. Here is an example: Firebase - Multiple users simultaneously updating same object using its old value
This does not mean, obviously, that back end data is always shared... In many cases each user accesses his own copy of back end data that is stored in a database.

Chrome extension manage webRequest lifetime

I am making an extension that needs to capture POST data directed to a site and once the site response confirms success, change some local data to reflect it.
The issue is, the POST data is located in requestBody from the onBeforeRequest event, while the success confirmation is in the onCompleted event. I understand that the lifetime of a webRequest should be managed using its unique requestId, but I am using an Event Page and therefore trying to avoid the use of global variables.
eventPage.js:
function continueListening(requestDetails){
function finishListening(completeDetails){
if (completeDetails.requestId === requestDetails.requestId){
doStuff(requestDetails, completeDetails);
chrome.webRequest.onErrorOccurred.removeListener(finishListening);
chrome.webRequest.onCompleted.removeListener(finishListening);
}
}
chrome.webRequest.onErrorOccurred.addListener(finishListening,{urls:["*://site*"]});
chrome.webRequest.onCompleted.addListener(finishListening, {urls:["*://site*"]});
}
chrome.webRequest.onBeforeRequest.addListener(continueListening, {urls:["*://site*"]});
I decided to try nesting listener registrations for the finalized request in order to provide them with the scope to compare requestIds with the initial request containing the form data. This appears to work, but I am concerned about a potential race condition between the resolving of the webRequest and the registration of the nested listener intended to listen for it, leading to any number of useless unremoved listeners.
The other option I see is to store the requestDetails in chrome.storage.local and check them against the completeDetails once they arrive. My main hesitation there is that if for whatever reason execution is interrupted the local disk space could be polluted with unresolved requests.
Is there a better way of doing this?
EDIT: Unfortunately although I believed I was making an Event Page, I did not have persistent:false in my manifest. As I learned when I added it, Event Pages do not even support webRequests. The Event Page equivalent, declarativeWebRequest, seems to have died in the beta channel. So making it a Background Page seems to be the necessary solution.

$rootScope is lost after refresh

I have a data-binding to $rootScope.someArray in my someData.view.html. I have written a Data service to load data and populate $rootScope.someArray and have called that service in my App's "run" method. Now If I am on the someData.view.html page and hit refresh(F5) all the data vanishes. Although if I go to home again and navigate to this html page, every thing comes back.
When I put a debug point on the place in DataService code where $rootScope.someArray is being populated, I can see data getting fetched from the backend but somehow it's lost.
Basically angular won't have the data on refresh. If you want retain you data, you need to use,
session service or local storage service based on your need (Don't forget to clear on log out).
But Putting all the data in local storage services or putting sensitive data in the local storage services is not advisable. So you need to call the Back end method and assign the data to the variable in the controller init (call using ng-init).
Note : Don't dump your array of data in RootScope. AngularJs team
itself suggesting that not to use. Instead of this use Angular
Services (not Factory) and make use this services where ever you want.

How to ensure javascript single page application to be executed on single browser tab only

I am building SPA application is emberjs framework and I need to ensure that the application instance is running only once (on single tab) on same domain.
Analogy of mutex to prevent multiple instances known from desktop application development world.
There are some solution I am considering just now like using localStorage locks or window.postMessage or SharedWorker but non of them looks bulletproof to me.
Do you have some ideas?
Thanks is advance.
I've used localStorage to make sure when users log out in one tab it logs them out in other tabs and it's worked quite well.
Bind to the storage event on the window object and use the event.key/event.newValue keys to determine what action to take. You can also use the event.url key to make sure the storage event is firing from the correct page. In my code I set a logged-out flag if the url, key and newValue data validates.
Bind to the focus event on the window object and check the value of the logged-out flag and auto-logout the user if it's set to true.
For my purpose I had to initialize the localStorage data to "not logged out" on page load because the storage event will not fire if you don't actually change the value of the localStorage key you're watching. I.e. if the value is blah and you set it to blah, no event will fire.
This works back to IE 8 too.
For your purpose you could set a localStorage key/value when someone logs in and block the page from working if that key/value is already set. Maybe set a timestamp as the value so if someone doesn't properly logout they can get back in after so many seconds. Then set an interval to update the timestamp while the user is logged in.
This is untested, if you go down this road I'd be interested to see how it works for you and what you had to do to make it work.

Categories