Observables and Subscriptions - angularjs

Can anyone explain to me Observables? They keep referring to observables as like promises. If I can call a method and return data, why do I need an observable?

Angular is non blocking having promises/Observables allows your code to continue to run while the data you have requested is retrieved.

Promises sugar coat the callback pattern, do this then that then other. A Promise will act on data and either return a value or an error.
Since the creation of JavaScript, event listeners have been listening to and reacting to events in the browser. Observables are the latest and greatest abstraction of the observer pattern. It doesn't matter what the data source is, you can wrap an Observable around it.
When you are dealing with a stream of data, a Promise isn't of any use to you because the stream may not end, Observables solve the problem. Angular 2 uses Observables instead of Promises for dealing with HTTP.

Related

Simultaneous async API calls in react hooks

I've been using hooks in my React project for a while now and have developed a hook for getting data, similar to many others, which I use like this.
const [callApi, isLoading, result, errrors] = useData();
callApi is a function which you call with your data and axios config, it makes the API call and updates the other variables. I deal with the result in a useEffect() call which sets the state when it receives new data. It's fairly simple.
The problem is that while it works very well for one request at a time, it has a single isLoading state and a single result state, which is no good if it's called before the previous call is finished. Let's say my user sending a message to his friends and the UI shows a list of friends with a "send message" button next to each name, they might click 3 buttons and make 3 calls in quick succession. We then have a race condition to see which one sets the result first.
I'm used to imperative programming with promises, in my old Angular code the button click would call an event handler which would call the api and the promise .then() would then deal with the result. This could happen 100 times simultaneously and each one would resolve seperately and then update the UI.
So my question is, is there an idiomatic way of doing this declaratively using react hooks so that I can fire off multiple requests and deal with the loading/result/errors separately?

How trigger changes in controller from a service WITHOUT employing $watch, $broadcast, $emit, etc

I have a bunch of hierarchically arranged components, namely:
partner component, that works with partner organizations, knows how to update or remove them, etc.;
leader component, that works with leader organizations, knows how to deal with leader organizations;
list component, than displays to the user both partner and leader organizations;
a service - when partner or leader components removes an organization, info on this organization is passed to the list component so that these changes are reflected in front immediately.
I cannot provide code samples on this, it's too big, moreover my question mostly requires a conceptual advice rather than code issues.
Right at the moment it perfectly works - components are doing their job sending data to the service:
IndexCollection.setIndexes(
vm.leaderIndex, vm.partnerIndex, 'added_l', response.id
);
the service does it's job and pushed changes to a variable, which I $watch in the list component to trigger respective actions like this:
$scope.$watch(() => IndexCollection.indexes, function() {
let indexes = IndexCollection.indexes;
switch (indexes.message) {
case 'deleted_p':
removePartner(indexes);
break;
case 'deleted_l':
removeLeader(indexes);
break;
case 'added_l':
addLeader(indexes);
break;
}
});
My question is of a more theoretical essence. Is there a possibility to trigger real-time actions from service in the list component without using$watch, $emit, $broadcast and other standard tools we usually use in this regard?
Can I somehow achieve the same result by means of using callbacks? I mean, when a change in service occurs, it triggers immediate action in the respective controller?
While using $watch may solve the problem, it is not the most efficient solution.
You might want to change the way you update and retrieve the data of your service.
The component controllers should manipulate the data stored in your service with functions in your service based on actions/events triggered from your component and you inject the service in the component.
MyDataService.getIndexCollection() {}
MyDataService.putIndexCollection() {}
Then you pass the data down to all your directives and components via require or bindings for components or isolated scopes for your directives.
For example once the partner components edits the data on the service you fetch the data again from your service and the updated data will be passed to your list component and update the view via $apply() if needed.

Use of 'then' in ReactJS

For ease in explaining the significance of 'then', could anyone tell me what is happening in this code?
fetchComments().then(response => {
this.setState({
comments: response.comments
});
});
fetchComments returns a promise (probably; it could just be a "thenable"*). A promise is something that will be either resolved or rejected at a later point in time (typically**). then is used to hook up a handler that will be called when the promise is resolved (and optionally when it's rejected, if you pass a second function into then; otherwise you'd use catch).
In this case, that code says that when/if the promise returned by fetchComments resolves, use the resolution value to set the state of the React component using the comments property of that resolution value.
More about promises in this MDN article and in the Promises/A+ spec.
* See the Promises/A+ spec for what a "thenable" is.
** If you use then on a promise that's already resolved or rejected, you're guaranteed by the native promises in JavaScript that your handler will still be called asynchronously. That wasn't always the case with some early promise-like implementations, which would either call your callback asynchronously (if the promise wasn't already settled) or synchronously (if it was), which was...chaotic and unhelpful. JavaScript's native promises and any really good promise library guarantees consistent callback behavior.
I am answering this question bit late but may be helpful to someone at some time.
Let's Start:
From the above code you pasted, I can give you a hint that whenever you see a keyword then in any Javascript code snippet, that is an asynchronous function using promise.
Promise: are objects which store information about whether or not those events have happened yet, and if they have, what their outcome is.Usually, promise will handle success (a.k.a resolve in js code) and failure(a.k.a reject in js code) and also both. So when we create any async functions, the promise is created inside these async functions.
Promise.then: then allows us to assign event handlers to a promise. Depending on the arguments we supply, we can handle success, failure, or both and the return of then is also a promise which means it can handle more events.
And finally to get to the code above, fetchComments is a promise which is an async function, and when the response is resolve it is updating the state of the comments and additionally here we can also handle error scenarios using .catch or even by adding another then
and to end, below link has a nice explanation:
A nice tutorial on Promise and then in javascript is here
Function fetchComments 'll fetch Data and return one Promise then give them to state comments :). But I think you should read here^^.
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise

what does the term 'Promise-based Http client' mean?

While going through the Redux middleware, I have come across Axios which is 'Promise-based HTTP client' to make Ajax request from browser. Could any body explain about this term and some info about axios?
Before Promise's comes into the picture there is something called Callback to handle asynchronous calls/code. But the main issue with callback is that when it gets nested and more nested it becomes very messy code and harder to understand even for the writer of the code.
To make it bit cleaner Promise comes into the picture which is cleaner in nature, Avoid callback hell problem in nodejs programming.
Moreover the concept async/await is also best fit with the promise instead of callback.
Hope you understand now. Comment below in case of any doubt.
From MDN:
A Promise is a proxy for a value not necessarily known when the
promise is created. It allows you to associate handlers with an
asynchronous action's eventual success value or failure reason. This
lets asynchronous methods return values like synchronous methods:
instead of immediately returning the final value, the asynchronous
method returns a promise to supply the value at some point in the
future.
A Promise is in one of these states:
pending: initial state, neither fulfilled nor rejected.
fulfilled: meaning that the operation was completed successfully.
rejected: meaning that the operation failed.
A promise-based client returns promises rather than accepting callbacks.

Is it always save to use $scope.$apply?

Sometimes i need to use $scope.$apply, for example when i use jQuery ajax or some non-angular-js eventlisteners. In those cases i have an asynchronous callback and there i use $scope.$apply so that changes to the scope are picked up by angular and watches are triggered. Please correct me if that is the wrong use of $scope.$apply.
This seems to work and the view is updated. However in some rather rare cases I get a "digest already in progress" error. I don't see how this can be possible, since the callback is not synchronous. So I wonder if it is possible that my asynchronous callback with the $scope.$apply in it can by chance collide with an ongoing digest? If so, how can I prevent this from happening?
edit:
One possibility to check for a digest is checking $$phase: if (!$scope.$$phase) $scope.$apply() but this is an anti-pattern as the angularjs wiki says: https://github.com/angular/angular.js/wiki/Anti-Patterns
I want to fully understand why it is possible that I encounter a digest in an asynchronous callback. And why this is an antipattern.
I recently asked a similiar question on why if (!$scope.$$phase) $scope.$apply() is an anti-pattern here: Why is using if(!$scope.$$phase) $scope.$apply() an anti-pattern?
The answer there also contains the answer to this question.
You are calling $apply on an existing scope, so it's definitely possible that you are calling apply while it is currently digesting. Some people might suggest checking $$phase but that has been discouraged as an anti-pattern
You have two options if you are running into this problem, even occasionally. One is to do as the anti-pattern implies and make sure your $scope.$apply is as high as possible up the chain.
However, this won't help if you are asynchronously calling $apply on the same $scope in rapid succession. The answer then is often to throttle the $apply so that it only happens every few hundred milliseconds. This is a common practice when using something like socket.io that can fire events which could cause you to re-apply many times.
I think, that its normal, but it will be better to move code to services and resources with angular style. To prevent error you can check current state
scope.$$phase
To prevent calling $apply
Async Callbacks are an appropriate time to use the $apply, there are edgecases I have run into as well where i get that error. They are usually because I am doing something wonky, I have found that a "Conditional Apply" works well for these.
if(!$scope.$$phase) {
//$digest or $apply
}
AngularJS : Prevent error $digest already in progress when calling $scope.$apply()

Resources