RxJS v6.3 pipe - How to use it? - rxjs

I just created a new Angular app that installed the new RxJS v6.3 (released 6 days ago), which "fixed" a problem with pipe and strong typing.
With v6.2 I could specify only the final returning value of the pipe (in this case, .pipe<User>, like this:
getStatus(): Observable<User> {
return this.http.get('/user/status')
.pipe<User>(
tap(foo, bar),
finalize(() => this.requestEnded()),
map((resp) => new User(resp.user)));
}
But in the new version they removed that possibility in the Observable class (they fixed this line from v6.2.2, to this in v6.3). The IDE complains with this message:
Expected at least 0 arguments, but got 1 or more.
Now I am forced to specify types for every function in the pipe, something like this:
getStatus(): Observable<User> {
return this.http.get('/user/status')
// If I have 3 piped functions I have to specify all 3 types
.pipe<{}, {}, User>(
tap(foo, bar),
finalize(() => this.requestEnded()),
// I even have to specify type for this parameter (resp)
map((resp: {user}) => new User(resp.user)));
}
Was this really intended? Note that this is a "fix" to pipe, which means to me that pipe was always supposed to work like that. Or am I using it the wrong way?
I even had this function that worked nicely, I just passed in some "common pipes" that I wanted to execute for every request:
logIn(username: string, password: string, remember: boolean) {
return this.http.post('/user/login', { username, password, remember })
.pipe<User>(
...this.commonPipes(),
map(resp => new User(resp.user)));
}
But now, how am I supposed to specify types for that?
This change was introduced in v6.3 which says it "fixes" some error with pipe (it references this issue). I write "fixes" because for me it broke things, it's not backwards compatible, and I haven't found a "how to upgrade" guide that explains how to use the new, fixed pipe().

The problem was that the spread syntax could only be used in a couple of versions in which the signatures for pipe were 'fixed'. However, those 'fixes' essentially broke all type checking for pipe - which was far worse, so they were reverted and changed again.
As noted in this issue, using the spread syntax with pipe requires TypeScript 3.0 - as it supports tuple parameter extraction and spreading.
As an alternative to having commonPipes return an array of operators, you could look at using the static pipe function to compose the operators into a single operator that can then be passed to an observable's pipe method.
Have a look at my Combining Operators article.

Related

Kamailio 4.4 seturi Only Accepts Explicit Strings?

I've been working at implementing a simple serial forking described in the TM module's documentation (the Q values are stored as a priority weight in a mysql table) where my proxy is querying a database to determine to what domain to forward to.
I've verified through extensive use of xlog that a variable I'm using to build the new URI to use with seturi is getting everything correctly. I use an append_branch call in a subsequent while loop iterating over my sql query results, which doesn't have any problems with taking a very similarly formatted parameter. However, when I go to restart Kamailio it simply gripes at me that a string is expected. The line it corresponds to from console is just the seturi call. I've tried casting as a string, but that doesn't seem to be part of 4.4 (or my syntax is wrong).
I've thought about building the URI strings and storing into avp, but I suspect I'd have the same problem.
For reference, this is what I'm doing:
$var(basedest) = "sip:" + $var(number) + "#" + $(dbr(destination=>[0,0]))+ ":" + $var(port);
seturi($var(basedest));
And what it's outputting when trying to load the config:
<core> [cfg.y:3368]: yyerror_at(): parse error in config file //etc/kamailio/kamailio.cfg, line 570, column 9-22: syntax error
<core> [cfg.y:3371]: yyerror_at(): parse error in config file //etc/kamailio/kamailio.cfg, line 570, column 23: bad argument, string expected
Naturally, when I put $var(basedest) in double quotes, it's literally interpreted as a string. Single quotes behave similarly. Is there something I can do to work around this? When I feed it an explicit hardcoded string, it's happy as a can be and the routing works fine. When I try to do something very simple like the above, it gets upset. If possible, I'd like to avoid updating as I initially grabbed Kamailio from the yum repo.
Thanks in advance - this has been bugging me a good while.
Apparently, not a new problem. I ended up finding out what I can do to work around it.
For reference, seturi and $ru pseudo variable refer to the same thing. So basically you'd just do:
$var(mynewru) = "sip:user#domain:5060";
$ru = $var(mynewru);
This would achieve the same thing I was originally attempting to do before based on the TM module's documentation. For serial forking, issuing some number of append_branch calls is fine.

Get last value from incomplete observable

There is an incomplete observable which can have or not have a replay of n values. I would like to get the last value from it - or just the next one if there is none yet.
This works for first available value with first() and take(1) (example):
possiblyReplayedIncomplteObservable.first().toPromise().then(val => ...);
But for the last value both last() and takeLast(1) wait for observable completion - not the desirable behaviour here.
How can this be solved? Is there a specific operator for that?
I had a solution for ReplaySubject(2) that 'drains' the sequence to get the latest element and if the sequence is empty simply takes the last element, yet, it was cumbersome and did not scale well (for example, if you decide to increase the replay size to 3). I then remembered that Replay/Behavior subjects tend to be hard to manage when they are piped. The simplest solution to that is to create a 'shadow' sequence and pipe your ReplaySubject into it (instead of creating it by transformation/operation on your ReplaySubject), hence:
var subject$ = new Rx.ReplaySubject(3);
var lastValue$ = new Rx.ReplaySubject(1);
subject$.subscribe(lastValue$); // short hand for subject$.subscribe(v => lastValue$.next(v))
lastValue$.take(1).toPromise().then(...);
========== Old solutions, ignoring the ReplaySubject(2) =================
After reading the comment below, the correct code is:
Rx.Observable.combineLatest(possiblyReplayedIncomplteObservable).take(1).subscribe(...)
and not
Rx.Observable.combineLatest(possiblyReplayedIncomplteObservable).subscribe(...)
This is due to the fact the promise is a "one time" observable. I think the toPromise() code resolves the result only on completion.
The take(1) will not affect your original stream since it operates on the new stream which is created by combineLatest.
And actually, the simplest way is:
possiblyReplayedIncomplteObservable.take(1).toPromise().then(...)

greenline Xcode EXC_BAD_INSTRUCTION on NSUserDefaults Optional

I've been writing an app that involves using NSUserDefaults to store a few Int variables and it's been working fine. I thought I was finished and was doing some final testing and one of the first lines of code that I wrote, and that has been working consistently before, has failed me.
Apparently the green line error is supposed to occur if I try to unwrap an optional that has a value of nil, but this variable is still very much an optional
var savedTotalSeconds: Int? = userDefaults.objectForKey("totalSecondsKey") as Int?
Why would this possibly return an error? It was working fine before and I only changed things I thought were unrelated to it. In the app I have a button to remove this stored value via:
userDefaults.removeObjectForKey("totalSecondsKey")
What could possibly have gone wrong?
Try using 'as? Int' instead of 'as Int?'
The difference is that the first one tries, and might fail, at casting to Int. That failure will be captured in the optionality of the resulting variable.
The second one tries to coerce the object to 'Int?'.

Dotted parameter names and/or variables in R

For a Ruby project I need an OpenCPU server to process some statistics by R packages. OpenCPU has an JSON REST API, so with Ruby I can easily hook into that to communicate with R. So far, so good.
One of those packages has a strange (at least to me) syntax.
add <- function(.argument1, .argument2) {
return(.argument1 + .argument2)
}
So this is just an example, not the actual function. The part I found weird are those points in front of parameters. When I suggested to remove those points, the developer of the package said that it was meant to hide the variables from the overview of variables in IDE (R-Studio). It sounds to me like he wanted to make the parameters, what we call it, private, or at least to scope it somehow. I searched the internets to explain this feature of R, but found nothing.
The actual problem is: we use Ruby, Ruby translates data into JSON and sends it to OpenCPU. OpenCPU looks up for the right package/function, passes arguments and executes it. Then it returns to OpenCPU which makes a JSON response. Ruby's >1.9 Hash syntax that we prefer to work with looks like:
{ argument1: 4, argument2: 3 }.to_json
# => { "argument1": 4, "argument2": 3 }
instead of older forced by the package arguments:
{ ".argument1" => 4, ".argument2" => 3 }.to_json
# => { ".argument1": 4, ".argument2": 3 }
So in desperate search for an argument to convince the R-developer not to use the dots, my question was still unanswered: does this point in front of the parameters have a real functionality in R or is it just a hack to exclude the variables from the IDE?
I think you will find that the reason comes from the default behaviour of the ls function in R which does not return objects beginning with a point. This can be modified by the all.names parameter:
all.names a logical value. If TRUE, all object names are returned. If FALSE, names which begin with a . are omitted.
It is quite common for more technical functions or variables to be "hidden" in this way, e.g. .Machine, .Options, .Fortran, .dynLibs

Is there a shortcut to swap/reorder parameters in visual studio IDE?

I have a common issue when working with code in the IDE:
string.Concat("foo", "bar");
and I need to change it to:
string.Concat("bar", "foo");
Often I have several of these that need to be swapped at once. I would like to avoid all the typing. Is there a way to automate this? Either a shortcut or some sort of macro would be great if I knew where to start.
Edit: changed to string.Concat to show that you can't always modify the method signature. I am only looking to change the order of the params in the method call, and nothing else.
<Ctrl> + <Shift> + <t> will transpose two words, so it would work in your case. Unfortunately I don't see this working (without multiple presses) for functions with larger parameter lists...
I had a lot of code with this function:
SetInt(comboBox1.Value + 1, "paramName", ...
SetInt(comboBoxOther.Value, "paramName", ...
And I needed to swap only the first two parameters;
I ended up using some text editor with regular expression management (like Scite), and using this one saved me hours:
Find: SetInt(\([.a-z0-9]+[ + 1]*\), \("[a-z0-9]+"\)
Replace: SetInt(\2, \1

Resources