Why to use observables instead of Ajax? - javascript

Why should I use an HTTP observable method like this:
this.http.get("MyURL")
.subscribe(
(_url: any) => {
//TODO My job
},
(error: any) => {
//TODO My job
},
() => {
//TODO My job
});
Instead of use an AJAX method like this:
$.ajax({
url: "MyURL",
success: function (result) {
//TODO My job
},
error: function () {
//TODO My job
}
});
I mean, what are the benefits and harms?

Why would you use an external library to do something angular is already capable of? Why would you actually use jQuery at all in combination with angular?
I think a better title for your question would have been, why use observables at all. I have had the same question when I started with angular, but after working with angular for over a year and having worked a lot with observables and rxjs over that period of time I have learned the following.
1- You cannot cancel promises
Lets say somebody goes to screen A, and you fetch some data like so.
fetch(/** some end point */)
.then(res => res.json())
.then(() => {
// Handle the request here
});
And by the time you are able to handle the request, the user leaves screen A. In most cases that is not a big deal, but because you want to do things the best way possible you would preferably cancel the handling of the request. With native promises, that's simply impossible. Read this article for great explantion on this
With observables, this becomes trivial. You can unsubscribe from an observable and that will ensure no unnecessary code is executed.
Pro tip: In angular you would do this in the ngOnDestroy life cycle of a component.
2 - Native promises have 2 methods, rxjs has many many more.
If you are using the native promises implementation, the only things you can do are then and catch (on a promise instance). This might seem more than enough, but with rxjs you can do many many more things.
Example
Lets say your /article/:id end point sometimes returns empty values because there is no article found. In promises your code will look something like this.
fetch('/article/5')
.then( res => res.json())
.then( res => {
if ( res !== undefined) {
// do something!
}
});
In rxjs this looks much cleaner, in the case of wanting to only do something with the data if its there. This might not seem as a big improvement, but in production you will find yourself wanting to do much much more than filtering out undefined values.
this.http.get("MyURL")
// p.s this line of code might not be needed depending on ur
// angular version
.map( res => res.json())
.filter( res => res !== undefined)
.subscribe(res => {
// Do something!
});
My advice for you would be to use toPromise wherever you are doing something simple, and to gradually use more and more rxjs operators once you need them. map, filter and takeUntil would be a good starting point.
I could go on showing you things you can do with rxjs that are hard to implement with promises, but there are lots of articles out there that do a better job than me explaining that.
TLDR
You can write cleaner asynchronous code and do more things with less code.

Please read the below link for better information :
https://angular-2-training-book.rangle.io/handout/observables/observables_vs_promises.html
What it seems like it is used majorly because Observables can define both the setup and teardown aspects of asynchronous behavior.

Fundamentally, they're the same thing. It's really just the implementation and usage that differ, so it becomes a matter of preference really.
Observables (which generally refer to the "RxJS" library, though not always) generally have a subscribe() method which lets them listen for changes, and have hooks for onNext() (something happened), onError() (something went wrong), and onComplete() (all done).
jQuery's AJAX syntax is a more "classic" callback structure, where you call the function and provide it with callbacks directly. It also has another syntax which allows you to add them as subsequent functions (.done() and the like).
When talking about JavaScript specifically though, nowadays I would argue that the Promise syntax is the most popular, as it is standardized in ECMAScript 6 and is natively supported by most browsers nowadays. fetch() is a native implementation of doing AJAX requests with Promise syntax.
At the end of the day, neither is particular better or stronger at the end of the day, and it really just boils down to personal preferences and past experience (for example, Observables are popular with developers who have Java experience, since Observables are used pretty frequently in Java).
Out of the three, only the Promise one has any real advantage, which is that it is natively supported by modern browsers (whereas the other two require a third-party library). But if you're already using a third-party library for something else, that's not a huge benefit.

Related

Is it ever better to use Node's filesystem sync methods over the same async methods?

This is a question about performance more than anything else.
Node exposes three different types of methods to accomplish various filesystem tasks:
Promises API (async)
Callback API (async)
Synchronous API (sync)
I've read more articles and stackoverflow answers than I can count, all of which claiming to never need the sync methods.
I recently wrote a script which required a couple directories to be made if they didn't already exist. During this, I noticed that if I used the async/await methods (primarily fs.promises.mkdir and fs.promises.access), the event loop would simply continue to the next async bit of code, regardless of the fact that the next bits require those directories. This is expected behavior, after all, it's async.
I understand this could be solved with a nice little callback hell sesh, but that isn't the question, whereas the idea that the promises api can be used over all other methods is.
The question then becomes:
Is it ever better to use Node's filesystem sync methods over the same async methods?
Is it ever truly required in situations like this to block the process?
Or said differently:
Is it possible to completely avoid sync methods and ONLY use the promises api (NOT promises + callbacks)?
It seems like using the sync methods (given my situation above, where the directories are required to be there before any other call is made) can be EXTREMELY useful to write readable, clear code, even though it may negatively impact performance.
With that being said, there's an overwhelming level of information to say that the sync api is completely useless and never required.
Again, this purely caters to the promises api. Yes, callbacks and promises are both async, but the difference between the job and message queues makes the both api's completely different in this context.
PS: For additonal context on examples, I've provided a code sample so you don't have to imagine my example ;)
Thanks! :)
// Checks if dir exists, if not, creates it. (not the actual code, just an example)
// Sync version
if (!fs.existsSync(dirPath)) {
fs.mkdirSync(dirPath);
}
// Async version
try {
await fs.promises.access(dirPath);
} catch {
await fs.promises.mkdir(dirPath);
}
It depends on the situation. The main benefit of the sync methods is that they allow for easier consumption of their results, and the main disadvantage is that they prevent all other code from executing while working.
If you find yourself in a situation where other code not being able to respond to events is not an issue, you might consider it to be reasonable to use the sync methods - if the code in question has no chance of or reason for running in parallel with anything else.
For example, you would definitely not want to use the sync methods inside, say, a server handling a request.
If your code requires reading some configuration files (or creating some folders) when the script first runs, and there aren't enough of them such that parallelism would be a benefit, you can consider using the sync methods.
That said, even if your current implementation doesn't require parallelism, something to keep in mind is that, if the situation changes and you find that you do actually need to allow for parallel processing, you won't have to make any changes to your existing code if you had started out by using the promise-based methods in the first place - and if you understand the language, using the Promises properly should be pretty easy, so if there's a chance of that, you might consider using the Promises anyway.

XMLHttpRequest Promise, nested in some sync code

Why is a sync xmlhttprequest deprecated ?
I would appreciate if the browser waits for the data instead of
open it for further clicking without finalizing the data-query.
I would like to write a program with just one step after the other.
Moreover the code should be properly structured and I wonder how
I can realize this without the promise-hell.
Is there any sync alternative to xmlhttprequest which is not "deprecated" ?
Thanks
Thomas
Why is a sync xmlhttprequest deprecated ?
Because it blocks the Event Loop and provides bad user experience to your end users.
Basically it "freezes" the page while it's happening.
I would appreciate if the browser waits for the data
That is not how browsers work though. Fortunately with practice the way browsers do work start to make an awful lot of sense - enough for languages that have previously used mostly synchronous I/O like Python to add "promises" too.
I would like to write a program with just one step after the other.
You can return responses from asynchronous calls in JavaScript. Using async/await code looks pretty similar and readable. See the async function mdn page.
Moreover the code should be properly structured and I wonder how I can realize this without the promise-hell.
"promise-hell" refers to the fact once a function does I/O all other functions it calls that. I'm not convinced that's a bad thing or that there is anything wrong with
async function sequence() {
let one = await fetch('/your-endpoint?someParam').then(x => x.json());
// do something with one
let param = one.param;
let two = await fetch('/your-other?param=' + param).then(x => x.json());
// do something with second call
}
sequence();
That is, async/await lets you write asynchronous code synchronously.
Don't expect to understand this all at once - it's ok it takes time.

Advice on creating asynchronous calls that depend on each other

I am attempting to create a library to make API calls to a web application (jira, if you care to know) I have my api calls working no problem, but I am looking to make the code a bit more readable and use-able. I have tried searching for my needs, but it turns out I am not sure what I need to be searching for.
I am having an issue with Asynchronous calls that depend on each other, I understand that I have to wait until the callback is ran to run my next item, but I am not sure of the best way to design this.
I really would like to make Chaining a feature of my api, which I would hope to look like this:
createProject(jsonProjectStuff)
.setLeadUser("myusername")
.createBoard("boardName")
.setBoardPermissions(boardPermissionJSONvar)
.addRole(personRoleJSONvar);
with this example, everything would have to wait on the createProject as it will return the project. createBoard doesn't rely on the project normally, but used in this context it should be "assigned" to the project made, setting the board permissions only relies on the createBoard to work. addRole is specific to the project again.
the questions I have are:
Is this possible to switch context like this and keep data in-between them without the need to run the function from the response hard coded?
If this is possible, is this a good idea? If not I am open to other schemes.
I can think of a couple ways to make it work, including registering the function calls with a dependency tree and then fulfilling promises as we go, although that is mostly conceptual for me at this point as I am trying to decide the best.
Edit 2/19/2016
So I have looked into this more and I have decided on a selective "then" only when it creating a new item doesn't relate directly to the parent.
//Numbers are ID, string is Name
copyProject(IDorName)
.setRoles(JSONItem)
.setOwner("Project.Owner")
.setDefaultEmail("noreply#fake.com")
.then(
copyBoard(IDorName)
.setName("Blah blah Name {project.key}"),
saveFilterAs(IDorName, "Board {project.key}",
"project = {project.key} ORDER BY Rank ASC")
.setFilterPermissions({shareValuesJSON})
)
I like this solution a lot, the only thing I am unsure of how to do is the string "variables", I suppose it could be "Blah blah Name " + this.project.key
either way I am unsure of how to give copyBoard or saveFilterAs access to it via the "then" function.
Any thoughts?
I've been using Nightmare (a headless browser) lately.
It has a fluent API that uses a nice design pattern.
Calling the API doesn't directly execute the actions, it only queues them and when you are ready to execute you must call the end function which returns a promise. The promise is resolved when the queue has completed its async execution.
For example, in your situation
createProject(jsonProjectStuff)
.setLeadUser("myusername")
.createBoard("boardName")
.setBoardPermissions(boardPermissionJSONvar)
.addRole(personRoleJSONvar)
.end() // Execute the queue of operations.
.then() => {
// All operations completed.
))
.catch(err => {
// An error occurred.
});
I feel like this pattern is quite elegant. It allows you to have a fluent API to build a sequence of actions. Then when you are ready to execute said operations you call end (or whatever). The sequence of operations are then completed asynchronously and you use the promise to handle completion and errors.

Difference between callback hell and nested promises

I recently started working with NodeJS and MongoDB(using Monk). This is when I came across the term "callback hell". In my code I was exactly doing the same thing. For an example-
DBCall(d1, function(e, docs){
if(docs.length!=0)
DBCall(d2, function(e, docs1){
if(docs1.length!=0)
DBCall(d3, function(e, docs2){
//doing something with docs,docs1,docs2
})
})
})
This is when I started reading on "promises", and I came across this article - https://strongloop.com/strongblog/promises-in-node-js-with-q-an-alternative-to-callbacks/
Since I needed both docs and docs1 inside the third callback so I used nested promises.
DBCall(d1)
.then(function(docs){
if(docs.length!=0)
return DBCall(d2)
.then(function(docs1){
if(docs1.length!=0)
return DBCall(d3)
.then(function(docs2){
//doing something with docs,docs1,docs2
})
})
})
From the above code snippet I have the following questions(/doubts) :
Apart from making the code more readable, does promises have performance benefits?
Nesting promises and callback hell looks similar to me. Is there actually any difference?
I am new to this concept of promises. Any help is appreciated.
Apart from making the code more readable, does promises have performance benefits?
Probably not.
Nesting promises and callback hell looks similar to me. Is there actually any difference?
Promises don't automatically prevent callback hell. But because they are more flexible than "simple" callbacks, they can be composed in different ways, which makes it easier to avoid callback hell.
Since I needed both docs and docs1 inside the third callback so I used nested promises.
Sometimes nested promises are unavoidable. However, there is no need to nest them if they don't have to be executed sequentially. You could execute them in parallel:
Promise.all([
DBCall(d1),
DBCall(d2),
DBCall(d3)
]).then(function(docs) {
// docs is an array: [docs, docs1, docs2]
});
Basically the purpose of Promises is to allow for functional composition and error handling, in a way that reads in a synchronous nature. Promises allow you to read code in a linear (maybe wrong term) or synchronous fasion.
This is sort of a broad question but take a look through these suggested links.
https://promise-nuggets.github.io/
https://blog.domenic.me/youre-missing-the-point-of-promises/
also this link
Edit:
After reading your updates, what you're essentially asking for is to join the promises (I think)
This SO Post gives some good info. Some of the better libraries have utility functions to help with this.
For example, if using bluebird take a look at the join function

Using AngularJS Promise

I am currently attempting to learn the AngularJS framework and I keep hearing about something called "promise". I have researched a little about it, although I cannot seem to find a thorough explanation to how and when to use "promises".
Can anyone please explain and provide a solution between using a promise, and not using a promise. What is the advantage of using a promise over not using one?
All answer are appreciated.
Thanks.
promises implementation basically provides an interface which define at least one method 'when' that return therefore, a "Promise", thus a result from an async operation.
Advantages are better code readability (and production as well), better reuse of the results without incurring on the scaring "callbacks hell", chainabilty, etc...
A simple scenario with jQuery:
without promises
$.ajax({
url: someurl,
success: function(data)
{
//do something with data
}
});
with promises
var p = $.ajax({ url: someurl });
$.when(p).then(function(data)
{
//do something with data
});
However, a better explanation: http://wiki.commonjs.org/wiki/Promises/A
The official documentation says that
The promise api allows for composition that is very hard
to do with the traditional callback (CPS ) approach. For more on this
please see the Q documentation especially the section on serial or
parallel joining of promises.
http://docs.angularjs.org/api/ng/service/$q
I think the easiest explanation could be that it's a much better and cleaner way to do a serial or very complex callbacks than the traditional way.
This is the link you can read more about the benefit of using promise:
promises specification

Categories

Resources