Can NgRx be used well with Promises instead of Observables? - javascript

So far I have only seen NgRx used with Observables.
Can the NgRx library be used with promises just as easily as with observables?
I am using Ionic 5 and I know it works with NgRx (with Observables for sure).
But now I want to use it not with an httpClient that returns Observables but rather with the Ionic Storage which returns Promises instead of Observables.
I would like to do some fancy redux ActionA->Reducer->Effect->ActionB->Reducer stuff with Ionic Storage.
So far I have found no info on the internet that it doesn't work with Promises. I thought I would ask since Angular has the httpClient built-in which afaik can only return Observable. I also found no programs that show NgRx being used with promises anywhere.

NgRx is not bound to Observables.
It's using the Redux patterns, which in its most basic form is a store and actions.
In other words, when you await a promise and dispatch an action to the store things just work the same as with http requests that are returning an Observable.

Related

What is the difference between a redux middleware and a redux-observable epic?

I would like to understand when it is appropriate to use a redux middleware over a redux-observable epic (and vice versa).
From the redux middleware documentation
It provides a third-party extension point between dispatching an action, and the moment it reaches the reducer. People use Redux middleware for logging, crash reporting, talking to an asynchronous API, routing, and more.
From the redux-observable documentation
While you'll most commonly produce actions out in response to some action you received in, that's not actually a requirement! Once you're inside your Epic, use any Observable patterns you desire as long as anything output from the final, returned stream, is an action.
My understanding is that an action in a redux middleware may or may not hit a reducer and if it does, it may or may not result in a change of state. In an epic you can produce a new action which may or may not hit a reducer or result in a change of state.
It looks like both can be used to enable side effects so the difference between the two is becoming a bit blurry to me.
Question: Is the FRP foundation the only thing that sets them apart or are there specific events in the lifecycle of an application that are better dealt with a classic middleware or an epic?
"Middleware" are a general type of thing that can be used to customize a Redux store. redux-observable is a specific Redux middleware, which lets you use RxJS logic to interact with dispatched actions.

Which redux middleware should I choose?

Following the guide, I came to a sorts of middlewares are there for redux application.
Redux Thunk, Redux Promise, Redux Promise Middleware, Redux Observable, Redux Saga, Redux Pack
It is just a matter of preference around which middleware we choose. But I'm not asking for choosing a convention.
I would like to know if there are any differences between them like performance, browser support, use cases, etc. Or anything else that I'm missing with. I tried a hard research for these but not able to find any article.
So that I can consider choosing a middleware for my application. It will also be great for me to choose middleware if I know the particular use case with different middlewares.
Or, all middlewares are just conventions and I may choose any one of them for any kind of redux application (small or large)?
To be able to choose one of these libraries we must take into account whether we are building a small or large application. Usability, code standards, and JavaScript knowledge may also be considered. All of them are similar.
redux-thunk​
Redux Thunk middleware allows you to write action creators that return a function instead of an action. The thunk can be used to delay the dispatch of an action, or to dispatch only if a certain condition is met. It incorporates the methods dispatch and getState as parameters.
​redux-saga​
redux-saga is a library that aims to make application side effects (i.e. asynchronous like data fetching and impure procedures such as accessing the browser cache) in a manageable and efficient way to execute. It's simple to test as it uses the ES6 feature called generators, making the flow easy to read as synchronous code.
​redux-observable​
redux-observable is a middleware for redux that is inspired by redux-thunk. It allows developers to dispatch a function that returns an Observable, Promise or iterable of action(s). When the observable emits an action, or the promise resolves an action, or the iterable gives an action out, that action is then dispatched as usual.
And others directly from their github source:
redux-promise
The middleware returns a promise to the caller so that it can wait for the operation to finish before continuing. This is especially useful for server-side rendering.
redux-promise-middleware
Redux promise middleware enables robust handling of async action creators in Redux: it accepts a promise and dispatches pending, fulfilled and rejected actions.
The middleware can also be combined with Redux Thunk to chain action creators.
redux-pack
redux-pack is a library that introduces promise-based middleware that allows async actions based on the lifecycle of a promise to be declarative.
Async actions in redux are often done using redux-thunk or other middlewares. The problem with this approach is that it makes it too easy to use dispatch sequentially, and dispatch multiple "actions" as the result of the same interaction/event, where they probably should have just been a single action dispatch.
This can be problematic because we are treating several dispatches as all part of a single transaction, but in reality, each dispatch causes a separate rerender of the entire component tree, where we not only pay a huge performance penalty, but also risk the redux store being in an inconsistent state.
redux-pack helps prevent us from making these mistakes, as it doesn't give us the power of a dispatch function, but allows us to do all of the things we were doing before.
From my personal experience ( I have used most of the middleware you have listed ).
Redux Saga is the way to go. It has a higher learning curve, but once you wrap your head around it, it becomes extremely powerful
Redux Saga
Allows for separation of concerns
Reduced Side Effects
Cancelable tasks ( amazing )
Parallel(like) processing
Once you understand redux saga, it becomes much easier to extend your application.
https://engineering.universe.com/what-is-redux-saga-c1252fc2f4d1

What is the difference between $q.race to Promise.race?

I am using Angularjs version 1.5.7 and $q.race function added in version 1.5.8.
I saw that there is function Promise.race and my question if there is any difference between those functions.
If there is difference should I copy the function from here: AngularJS: $q.race() in old angular versions
and it will works the same like $q.race?
Thanks in advance and sorry for my english!
JavaScript ES6 specifications introduced the method you described above, like Promise.race, Promise.all etc..
The difference is basically that angular has a built-in $q service in order to manage with promises.
This will trigger automatically the digest cycle in order to change everything that could be related to the data returned by the promises or all the involved operations.
If you are allowed to use ES6 specification, you can use directly all the built-in Promises of JavaScript, but then you have to manually trigger the $digest in order to make all the changes happen.
This is one of the main differences between the usage of $q or standard Promises in angularjs.
Moreover, there are a lot of related methods in angular which integrates with $q, like $http for example, and for your tests, you will have your life easier treating directly with $q.
So my suggestion is to use $q if possible.
The core difference is that $q.race will call $rootScope.$apply() under the hood to digest any changes that may occurred after executing your promise callback.
Promise A+ spec has noting to do with that since Promise.all, Promise.race are defined in ES6/ES2015 spec not in Promise A+ spec

RxJS + (async/await) for (multiple-event) use cases

I am writing a Javascript App to get data from sensors. I started using ES6 Promises + Generators using Bluebird and the Bluebird.cororutine in both (client and server), but it didn't work fine.
I was advised that Promises didn't work properly in (multiple-event) use cases, and that an alternative could be RxJS.
I've taken a look to RxJS, and it looks like can do the same as the Promises but even better.
I wanted to use generators (async/await) to write the async code to look as sync, and my question is:
Can I use RxJS + (async/await) or RxJS has already its own way to do the same as (async/await) ?
Thanks
Async/await is not part of ES6, it's scheduled for ES7. So you're probably not going to use it any time soon in JavaScript. TypeScript supports async/await for ES5 since 2.1.
It think you'll be able to use RxJS with async/await when it comes out. Async/await works with Promises, just like RxJS even though it mostly works with Observables. There are methods such as Observable.toPromise() to convert an Observables to Promises and most Observables also accept a Promise as a parameter.
So I think both are going to be well interchangable (I haven't tried thi personally).
If your primary interest is to make you code more readable than RxJS is a good choice to reduce callback hell.
These two examples show how to call multiple HTTP requests in order using Observable.concatMap() operator. Both examples are written in TypeScript but it should be basically the same in
ES6 as well. Also these examples use the new RxJS implementation (https://github.com/ReactiveX/RxJS):
Angular 2 + rxjs - how return stream of objects fetched with several subsequent http requests
How to use exhaustMap in ReactiveX/rxjs 5 in TypeScript

How do you 'intercept' all HTTP requests in an EmberJs app?

I would like to be able to capture all HTTP requests and responses, and modify them, before they get to the rest of an EmberJs app. I would like to do this globally - across the entire app. I have not been able to find this digging through the API. How can this be done?
(Modification is to perform some conditional logic based in certain headers, or to add or modify certain headers).
In AngularJS, you can accomplish this using something like this:
App.factory('AppHttpInterceptor', function($q) {
return {
request: function(req) {
//modify request
return req;
},
response: function(res) {
// modify response
return res || $q.when(res);
}
};
});
App.config(function ($httpProvider) {
$httpProvider.interceptors.push('AppHttpInterceptor');
});
First, it's important to note that Angular and Ember are not built to serve the same purpose. They are both javascript frameworks, and that's about where the similarities end. Another big factor in the difference of async requests in the two framework is Angular's integration of promises into it's async services. Ember async services are not promise based, and therefore response interceptors are not possible (see my note below).
AngularJS provides $httpProvider as a configurable singleton that returns a configured instance of $http as a promise object. Angular focuses on services rather than methods (although it does have a few methods it gives you), and that's what sets Angular apart from other frameworks like Ember, which give you a structure to build services, but doesn't provide services in it's core.
Instead, with Ember, you'd have to build a service and service provider concept yourself. You could take something like cerebris/ember-rest, and extend it in such a way as to use properties you describe. This library provides an Ember.resource method, which you could use prototype to extend from there:
Ember.ResourceAdapter.extend({
_prepareResourceRequest: function(params) {
params.beforeSend = function (xhr, settings) {
//set your xhr interceptors here
}
}
});
Edit: Clarification on use of $ajax in ember and $http in Angular (promises vs callbacks)
The biggest difference on how angular makes response interceptors possible, is that async requests in angular are promises, whereas $ajax calls are not. Without getting too much into the weeds, you can assign variables to each step of a promise, making it available for mutation/handling along every step of the way, whereas with $ajax, you can only perform operations when the data has completely returned. With Promises, assign variables to represent states at any point during the lifecycle of the promise, and using that reference, you can mutate the promise as needed, at any point in time prior to the event of the promise fully resolving.
Thus why it's possible to do request interceptors with $ajaxPrefilter but there is no good way to do response interceptors, using the abstract configuration approach with $ajax. To truly do in Ember what AngularJS does with $http, you need to create a promise based async request/response service, as opposed to utilizing non-promise based xhr requests such as $ajax.
jQuery does provide an $ajaxSetup() method, which you might be able to set a dataFilter property to and define a handler function, however this is not recommended. With angular, the $httpProvider can be configured by module, and through de-coupling and Separation of Concerns, this can become truly powerful, allowing you to encapsulate and cascade http interceptor configurations with a lot of control. Making the same changes to your ajax settings will register themselves on the global jquery namespace, and can cause conflicts if you need to grow your app.
One video I found particularly englightening on this subject was from ng-conf 2014: Christion Lilley: Going Postal with Angular Promises
Edit 2: addressing Ember.RSVP
While Ember.RSVP is indeed a promise class useable in the framework, it does not have any methods available to perform resource requests. This means you have to manually assign an http request instance to an instance of RSVP.deferred such that it resolves your http request before returning the promise.
This allows you to do interceptors on both sides of each individual request, but does not provide a solution for configuring interceptors for all requests. You'd have to create another function or service for that, and extend RSVP with this function.

Categories