How to call xhr in Dojo using TypeScript - dojo

I'm using Typescript (new to it), and Dojo, and I need to make an async call. This is pretty easy when you're not using TypeScript. But, the compiler is making things harder, especially because I do not allow "implicit any". I also like the lambda-style callbacks, but the compiler complained about the "implicit any" there, too. Mostly, I'm getting confused between the Deferred, and the Promise, and how to import the promise module.
Is there anybody with Typescript/Dojo experience who can tell me if I got this right? And, is there any way to improve it?
import xhr = require("dojo/request/xhr");
private getDataAsync(url:string, param:any):dojo.promise.Promise {
var deferred = new Deferred();
var options: any = {
handleAs: 'json',
query: {
'param': param
}
};
xhr.get(url, options).then(
lang.hitch(this, function(data:any) {
var returnValue = this.doSomething(data);
deferred.resolve(returnValue);
}),
function(err:any) {
deferred.reject(err, true);
}
);
return deferred.promise;
}
Moreover, do I even need to use Dojo's xhr here? Is there something built into TypeScript that wraps XMLHTTPRequest in a browser-neutral way, the way that dojo does?

I think the problem is that the Deferred and Promise classes in the dojo.d.ts appear to be long overdue for an update. They do not have a generic type parameter for the result type, and the then callbacks are just Function, so they capture nothing about the shape of the function. This doesn't take advantage of TypeScript 1.0, never mind 1.4.
Compare with es6-promise.d.ts, in which Promise<R> has a method then<U>, where R is the value coming out of the promise and U is the value produced by then's resolve handler, and thus the next promise will be Promise<U>. So chains of operations on promises are strongly typed and everything works beautifully.
If you make similar improvements to dojo.d.ts and set them a pull request, they'll probably be quite grateful! :)

Is there something built into TypeScript that wraps XMLHTTPRequest in a browser-neutral way
No. TypeScript has very minimal runtime environment only for helping the compiler generate valid code (pretty much only the __extends function).
I also like the lambda-style callbacks, but the compiler complained about the "implicit any" there, too
This is natural. The compiler does not know the result of the XHR, if you know it specify it using some interface, or you can tell the compiler that you don't want type safety and use any as you are doing already.
Update 1
I'm still stuck on the differences between dojo.promise.Promise, deferred.promise, and Deferred
Promise is a promise : https://github.com/promises-aplus/promises-spec
Deferred is something that has a promise (.promise) as well as nice handles (.resolve and .reject) to determine the fate of the said promise.

Related

Redux-observable returning some sample data

I am using redux-observable and I need to return some sample data as an Observable. I have the following code in one of my epics
const sampleFilteredStores = Observable.of([{ type: 'FILTERED_STORES', store: 'a' }, { type: 'FILTERED_STORES', store: 'b' }]);
const filteredStores$ = action$.ofType('SEARCH_STORES').mapTo(Observable.of(sampleFilteredStores).mergeAll());
return filteredStores$;
However when I run this I get an error
instrument.js:56 Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.(…)
What am I doing wrong here and how do I fix this?
Investigation
In the case of the example code you gave, the first thing we need to do is indent and format the code so that it's easier to understand what is happening.
const somethingEpic = action => {
const sampleFilteredStores = Observable.of([
{ type: 'FILTERED_STORES', store: 'a' },
{ type: 'FILTERED_STORES', store: 'b' }
]);
const filteredStores$ = action$.ofType('SEARCH_STORES')
.mapTo(
Observable.of(sampleFilteredStores)
.mergeAll()
);
return filteredStores$;
};
Exactly how you format your code is your choice, but I personally find something like this much more readable. It will help you debug but also significantly help any future maintainers of your code understand your intent.
mapTo
Now I can see right away one problem, which is that you're passing an Observable to mapTo, which is highly unusual in Rx. It's certainly not wrong 100% of the time, but 99.99% and even in the 0.01% there would be much clearer ways to show the desired intent.
Observable.of
Digging in further, I see two usages of Observable.of.
The first one that stuck out is you pass an Observable to Observable.of: Observable.of(sampleFilteredStores) The same advice as mapTo applies here, this is very uncommon and not recommended because it creates higher order Observables unnecessarily. I do see you use mergeAll() to flatten it, but that gives you an Observable that is basically identical to what sampleFilteredStores is without the indirection.
When I dig even deeper I notice another subtle, but critical thing, you pass an array of actions to Observable.of. This is also highly suspicious because that means you create an Observable that just emits an array of two actions, not emits those two actions sequentially directly. If the later is what you intended, instead you needed to pass the objects directly as arguments themselves. Observable.of(action1, action2, action3, ...etc). You may have gotten confused from seeing someone use Observable.from passing in an array, but that's different than Observable.of
Root Cause
Combining those discoveries I can now see that this epic actually emits an Observable, rather than actions, which is why you're receiving the error from redux. That Observable itself actually would emit an array of actions, so even if you had flatten that Observable out you still would receive the same error.
Solution
It appears the provided code is likely contrived either to simplify your question or as you were learning Rx or redux-observable. But in this specific case I believe you wanted to listen for SEARCH_STORES and when received sequentially dispatch two actions both of type FILTERED_STORES with differing store values.
Using idiomatic Rx, that could look something like this:
const somethingEpic = action => {
return action$.ofType('SEARCH_STORES')
.mergeMap(() => Observable.of(
{ type: 'FILTERED_STORES', store: 'a' },
{ type: 'FILTERED_STORES', store: 'b' }
))
};
Here we're using mergeMap, but since the Observable.of we flatten in emits synchronously we could have used switchMap or concatMap too, they would have had the same net effect--but that's not the case for Observables that emit async! So definitely study up on the various flattening strategy operators.
This chain can be described as: Whenever we receive object with the property type equals SEARCH_STORES, map it to an Observable of two objects (the FILTERED_STORES actions) that emit sequentially and synchronously.
Closing
Hopefully this helps! One thing to keep in mind when learning and using redux-observable is that it is almost entirely "just RxJS" that happens to be dealing with object which are "actions". So normal, idiomatic Rx is normal idiomatic redux-observable. Same with the problems you might encounter. The only real difference is that redux-observable provides the single ofType operator as shorthand to a filter (as the docs describe). If you have Rx issues in the future, you might find it helpful to refactor your examples to use filter and phrase them agnostic of redux-observable since the Rx community is obviously much larger!

Alternative to the try (?) operator suited to iterator mapping

In the process of learning Rust, I am getting acquainted with error propagation and the choice between unwrap and the ? operator. After writing some prototype code that only uses unwrap(), I would like to remove unwrap from reusable parts, where panicking on every error is inappropriate.
How would one avoid the use of unwrap in a closure, like in this example?
// todo is VecDeque<PathBuf>
let dir = fs::read_dir(&filename).unwrap();
todo.extend(dir.map(|dirent| dirent.unwrap().path()));
The first unwrap can be easily changed to ?, as long as the containing function returns Result<(), io::Error> or similar. However, the second unwrap, the one in dirent.unwrap().path(), cannot be changed to dirent?.path() because the closure must return a PathBuf, not a Result<PathBuf, io::Error>.
One option is to change extend to an explicit loop:
let dir = fs::read_dir(&filename)?;
for dirent in dir {
todo.push_back(dirent?.path());
}
But that feels wrong - the original extend was elegant and clearly reflected the intention of the code. (It might also have been more efficient than a sequence of push_backs.) How would an experienced Rust developer express error checking in such code?
How would one avoid the use of unwrap in a closure, like in this example?
Well, it really depends on what you wish to do upon failure.
should failure be reported to the user or be silent
if reported, should one failure be reported or all?
if a failure occur, should it interrupt processing?
For example, you could perfectly decide to silently ignore all failures and just skip the entries that fail. In this case, the Iterator::filter_map combined with Result::ok is exactly what you are asking for.
let dir = fs::read_dir(&filename)?;
let todos.extend(dir.filter_map(Result::ok));
The Iterator interface is full of goodies, it's definitely worth perusing when looking for tidier code.
Here is a solution based on filter_map suggested by Matthieu. It calls Result::map_err to ensure the error is "caught" and logged, sending it further to Result::ok and filter_map to remove it from iteration:
fn log_error(e: io::Error) {
eprintln!("{}", e);
}
(|| {
let dir = fs::read_dir(&filename)?;
todo.extend(dir
.filter_map(|res| res.map_err(log_error).ok()))
.map(|dirent| dirent.path()));
})().unwrap_or_else(log_error)

What is indirect object notation, why is it bad, and how does one avoid it?

The title pretty much sums it up, but here's the long version anyway.
After posting a small snippet of perl code, I was told to avoid indirect object notation, "as it has several side effects". The comment referenced this particular line:
my $some_object = new Some::Module(FIELD => 'value');
As this is how I've always done it, in an effort to get with the times I therefore ask:
What's so bad about it? (specifically)
What are the potential (presumably negative) side effects?
How should that line be rewritten?
I was about to ask the commenter, but to me this is worthy of its own post.
The main problem is that it's ambiguous. Does
my $some_object = new Some::Module(FIELD => 'value');
mean to call the new method in the Some::Module package, or does it mean to call the new function in the current package with the result of calling the Module function in the Some package with the given parameters?
i.e, it could be parsed as:
# method call
my $some_object = Some::Module->new(FIELD => 'value');
# or function call
my $some_object = new(Some::Module(FIELD => 'value'));
The alternative is to use the explicit method call notation Some::Module->new(...).
Normally, the parser guesses correctly, but the best practice is to avoid the ambiguity.
What's so bad about it?
The problems with Indirect Method Notation are avoidable, but it's far easier to tell people to avoid Indirect Method Notation.
The main problem it's very easy to call the wrong function by accident. Take the following code, for example:
package Widget;
sub new { ... }
sub foo { ... }
sub bar { ... }
sub method {
...;
my $o = new SubWidget;
...;
}
1;
In that code, new SubWidget is expected to mean
SubWidget->new()
Instead, it actually means
new("SubWidget")
That said, using strict will catch most of these instances of this error. Were use strict; to be added to the above snippet, the following error would be produced:
Bareword "SubWidget" not allowed while "strict subs" in use at Widget.pm line 11.
That said, there are cases where using strict would not catch the error. They primarily involve the use of parens around the arguments of the method call (e.g. new SubWidget($x)).
So that means
Using Indirect Object Notation without parens can result in odd error messages.
Using Indirect Object Notation with parens can result in the wrong code being called.
The former is bearable, and the latter is avoidable. But rather than telling people "avoid using parens around the arguments of method calls using Indirect Method Notation", we simply tell people "avoid using Indirect Method Notation". It's just too fragile.
There's another issue. It's not just using Indirect Object Notation that's a problem, it's supporting it in Perl. The existence of the feature causes multiple problems. Primarily,
It causes some syntax errors to result in very odd/misleading error messages because the code appeared to be using ION when it wasn't.
It prevents useful features from being implemented since they clash with valid ION syntax.
On the plus side, using no indirect; helps the first problem.
How should that line be rewritten?
The correct way to write the method call is the following:
my $some_object = Some::Module->new(FIELD => 'value');
That said, even this syntax is ambiguous. It will first check if a function named Some::Module exists. But that's so very unlikely that very few people protect themselves from such problems. If you wanted to protect yourself, you could use the following:
my $some_object = Some::Module::->new(FIELD => 'value');
As to how to avoid it: There's a CPAN module that forbids the notation, acting like a pragma module:
no indirect;
http://metacpan.org/pod/indirect
The commenter just wanted to see Some::Module->new(FIELD => 'value'); as the constructor.
Perl can use indirect object syntax for other bare words that look like they might be methods, but nowadays the perlobj documentation suggests not to use it.
The general problem with it is that code written this way is ambiguous and exercises Perl's parser to test the namespace to e.g. check when you write method Namespace whether Namespace::method exists.

Reuse the description of an existing Error when creating a new Error

I have the following code in Rust, which does not compile, but shows the intent of what I'd like to do.
pub fn parse(cursor: &mut io::Cursor<&[u8]>) -> io::Result<Ack> {
use self::byteorder::{BigEndian, ReadBytesExt};
use self::core::error::Error;
match cursor.read_u16::<BigEndian>() {
Err(byteorder::Error::Io(error)) => Err(error),
Err(error) =>
Err(io::Error::new(io::ErrorKind::Other, error.description(),
None)),
Ok(value) => Ok(Ack { block_number: value })
}
}
Essentially, I want to take the error description of an error returned by the byteorder library and use it to create the description of an error I'll pass back to the user of my library. This fails with packets.rs:166:58: 166:63 error:errordoes not live long enough, and I understand why.
The byteorder library solves this issue by wrapping an std::io::Result in the byteorder::Error::Io constructor. However, I don't want to take this route because I'd have to define my own error type that wraps either an std::io::Error or a byteorder::Error. It seems to me that my users shouldn't know or care that I use the byteorder library, and it shouldn't be part of my interface.
I'm a Rust newbie and don't yet know the idioms and best practices of the language and design. What are my options for dealing with this?
Your problem is in fact in that io::Error::new()'s second parameter is &'static str, while byteorder::Error::description() returns a &'a str where 'a is lifetime of the error object itself which is less than 'static. Hence you can't use it for io::Error's description.
The simplest fix would be moving byteorder::Error description to detail field of io::Error:
Err(error) =>
Err(io::Error::new(
io::ErrorKind::Other,
"byteorder error",
Some(error.description().to_string())
)),
However, you should seriously consider making a custom wrapper error type which encapsulates all "downstream" errors. With properly written FromError instances you should be able to write something like
try!(cursor.read_u16::<BigEndian>()
.map(|value| Ack { block_number: value }))
instead of your whole match. Custom error wrappers will also help you when your program grows and more "downstream" error sources appear - you could just add new enum variants and/or FromError implementations to support these new errors.
I cannot test your code so I can't be sure. Isn't the ref keyword enough?
Err(byteorder::Error::Io(ref error)) => Err(error),

MicrosoftAjaxMinifier doesn't seem to remove "unreachable code"

I'm using this with BundleTransformer from nuget and System.Web.Optimisation in an ASP.Net app. According to various docs this minifier is supposed to "remove unreachable code". I know it's not as aggressive as google closure (which I can't use presently) but I can't get even the simplest cases to work, eg;
function foo() {
}
where foo isn't called from anywhere. I can appreciate the argument that says this might be an exported function but I can't see a way to differentiate that. All my JS code is concatenated so it would be able to say for sure whether that function was needed or not if I can find the right switches.
The only way I've found to omit unnecessary code is to use the debugLookupList property in the web.config for BundleTransformer but that seems like a sledgehammer to crack a nut. It's not very granular.
Does anyone have an example of how to write so-called 'unreachable code' that this minifier will recognise?
Here's a place to test online
I doubt the minifier has any way of knowing if a globally defined function can be removed safely (as it doesn't know the full scope). On the other hand it might not remove any unused functions and might only be interested in unreachable code (i.e. code after a return).
Using the JavaScript Module Pattern, your unused private functions would most likely get hoovered up correctly (although I've not tested this). In the example below, the minifier should only be confident about removing the function called privateFunction. Whether it considers unused functions as unreachable code is another matter.
var AmazingModule = (function() {
var module = {};
function privateFunction() {
// ..
}
module.otherFunction = function() {
// ..
};
return module;
}());
function anotherFunction() {
// ..
}