RSJX Observable not returning data - group-by

The following code, when subscribed to, returns an expected array of objects.
this.store.select (this.selectors.evidenceSelector);
The objects include a 'subjectId' field.
This code, based on multiple examples on the web, returns nothing when subscribed to:
this.store
.select (this.selectors.evidenceSelector)
.pipe (
groupBy (ev => ev['subjectId']),
mergeMap (group$ => group$.pipe(toArray())),
);
The subscription never gets triggered...
Any suggestions?

Oh after reading again... I think I've figured out what's going on here.
toArray will only emit a value when the stream is closed. As you're listening from your store (which will never be closed), you'll never get anything under the toArray. You have to use something like scan if you want to accumulate and show a result on every new emission.

Related

Running into an issue with a mutation and component flickering with react-query

So, I am making a query everything my context API is updated via a form selection update..
So, order of operation is like so.
User makes a change to a form by selecting (one of possible many) from dropdown.
Change updates "context api" which resaturates the parent component.
Because the form key/values changed, I fire a mutation.
Mutation returns a value. So far, great.
But, when I repeat step #1 - #4, another component flickers with that updated value because at some point the "const" that is expecting a value is undefined... THEN, it has a value..
So, like so..
has a value...
...query api call...
has no value
...returns query
has a value
const ProductPage = (props) => {
const { question } = useContextStateWhatever();
/* Queries */
const { data = {}, isFetched } = useProductUpdatePrice({ questions });
const value = derivePriceFromResponse(data.products);
return (
<SomeComponentRendered value={value} />
)
So, you can see between the "old value" and request in query, that the passed "value" will be undefined. Then query returns, updated value.
I was hoping the query will return any previous value, but the "queryKey" changes with every selection of the form. Deep queryKey.
I was hoping I wouldn't have to then put this value into local state from within a useEffect, or use useRef and create hook to hand back "previous" value until new value is ready.... That's not what react-query is for, right? I mean, shouldn't I be able to make a query call whenever the "context api" changes, and not expect this latency diff of undefined. Any strategies to over come this?
Since the "queryKey" is different (mostly for normal form interaction) for each query, I can see how it can't hand back a previous value until it resolves etc.. any ideas?
Any thoughts?
I think the keepPreviousData: true option is what you are looking for. If the query key changes, you will the get the data from the previous query key, along with an isPreviousData: true flag. The background update will still happen, and then you’ll get the data for the new query key once it arrives. The query will stay in isSuccess status the whole time.

Returning value from a Scala Future

In the below code, I'm trying to do two operations. One, to create a customer in a db, and the other, to create an event in the db. The creation of the event, is dependent on the creation of the user.
I'm new to Scala, and confused on the role of Futures here. I'm trying to query a db and see if the user is there, and if not, create the user. The below code is supposed to check if the user exists with the customerByPhone() function, and if it doesn't, then go into the createUserAndEvent() function.
What it's actually doing, is skipping the response from customerByPhone and going straight into createUserAndEvent(). I thought that by using a flatmap, the program would automatically wait for the response and that I wouldn't have to use Await.result is that not the case? Is there a way to avoid using Await.result to not block the thread on production code?
override def findOrCreate(phoneNumber: String, creationReason: String): Future[AvroCustomer] = {
//query for customer in db
//TODO this goes into createUserAndEvent before checking that response comes back empty from querying for user
customerByPhone(phoneNumber)
.flatMap(_ => createUserAndEvent(phoneNumber, creationReason, 1.0))
}
You don't need to use Await.result or any other blocking. You do in fact have the result from customerByPhone, you're just ignoring it with the _ . I think what you want is something like this:
customerByPhone(phoneNumber)
.flatMap(customer => {
if(customer == null)
createUserAndEvent(phoneNumber, creationReason, 1.0)
else
Future(customer)
})
You need to code the logic to do something only if the customer isn't there.

Spark: How to structure a series of side effect actions inside mapping transformation to avoid repetition?

I have a spark streaming application that needs to take these steps:
Take a string, apply some map transformations to it
Map again: If this string (now an array) has a specific value in it, immediately send an email (or do something OUTSIDE the spark environment)
collect() and save in a specific directory
apply some other transformation/enrichment
collect() and save in another directory.
As you can see this implies to lazily activated calculations, which do the OUTSIDE action twice. I am trying to avoid caching, as at some hundreds lines per second this would kill my server.
Also trying to mantaining the order of operation, though this is not as much as important: Is there a solution I do not know of?
EDIT: my program as of now:
kafkaStream;
lines = take the value, discard the topic;
lines.foreachRDD{
splittedRDD = arg.map { split the string };
assRDD = splittedRDD.map { associate to a table };
flaggedRDD = assRDD.map { add a boolean parameter under a if condition + send mail};
externalClass.saveStaticMethod( flaggedRDD.collect() and save in file);
enrichRDD = flaggedRDD.map { enrich with external data };
externalClass.saveStaticMethod( enrichRDD.collect() and save in file);
}
I put the saving part after the email so that if something goes wrong with it at least the mail has been sent.
The final 2 methods I found were these:
In the DStream transformation before the side-effected one, make a copy of the Dstream: one will go on with the transformation, the other will have the .foreachRDD{ outside action }. There are no major downside in this, as it is just one RDD more on a worker node.
Extracting the {outside action} from the transformation and mapping the already sent mails: filter if mail has already been sent. This is a almost a superfluous operation as it will filter out all of the RDD elements.
Caching before going on (although I was trying to avoid it, there was not much to do)
If trying to not caching, solution 1 is the way to go

Play/Scala Template Block Statement HTML Output Syntax with Local Variable

Ok, I've been stuggling with this one for a while, and have spent a lot of time trying different things to do something that I have done very easily using PHP.
I am trying to iterate over a list while keeping track of a variable locally, while spitting out HTML attempting to populate a table.
Attempt #1:
#{
var curDate : Date = null
for(ind <- indicators){
if(curDate == null || !curDate.equals(ind.getFirstFound())){
curDate = ind.getFirstFound()
<tr><th colspan='5' class='day'>#(ind.getFirstFound())</th></tr>
<tr><th>Document ID</th><th>Value</th><th>Owner</th><th>Document Title / Comment</th></tr>
}
}
}
I attempt too user a scala block statement to allow me to keep curDate as a variable within the created scope. This block correctly maintains curDate state, but does not allow me to output anything to the DOM. I did not actually expect this to compile, due to my unescaped, randomly thrown in HTML, but it does. this loop simply places nothing on the DOM, although the decision structure is correctly executed on the server.
I tried escaping using #Html('...'), but that produced compile errors.
Attempt #2:
A lot of google searches led me to the "for comprehension":
#for(ind <- indicators; curDate = ind.getFirstFound()){
#if(curDate == null || !curDate.equals(ind.getFirstFound())){
#(curDate = ind.getFirstFound())
}
<tr><th colspan='5' class='day'>#(ind.getFirstFound())</th></tr>
<tr><th>Document ID</th><th>Value</th><th>Owner</th><th>Document Title / Comment</th></tr>
}
Without the if statement in this block, this is the closest I got to doing what I actually wanted, but apparently I am not allowed to reassign a non-reference type, which is why I was hoping attempt #1's reference declaration of curDate : Date = null would work. This attempt gets me the HTML on the page (again, if i remove the nested if statement) but doesn't get me the
My question is, how do i implement this intention? I am very painfully aware of my lack of Scala knowledge, which is being exacerbated by Play templating syntax. I am not sure what to do.
Thanks in advance!
Play's template language is very geared towards functional programming. It might be possible to achieve what you want to achieve using mutable state, but you'll probably be best going with the flow, and using a functional solution.
If you want to maintain state between iterations of a loop in functional programming, that can be done by doing a fold - you start with some state, and on each iteration, you get the previous state and the next element, and you then return the new state based on those two things.
So, looking at your first solution, it looks like what you're trying to do is only print an element out if it's date is different from the previous one, is that correct? Another way of putting this is you want to filter out all the elements that have a date that's the same date as the previous one. Expressing that in terms of a fold, we're going to fold the elements into a sequence (our initial state), and if the last element of the folded sequence has a different date to the current one, we add it, otherwise we ignore it.
Our fold looks like this:
indicators.foldLeft(Vector.empty[Indicator]) { (collected, next) =>
if (collected.lastOption.forall(_.getFirstFound != next.getFirstFound)) {
collected :+ next
} else {
collected
}
}
Just to explain the above, we're folding into a Vector because Vector has constant time append and last, List has n time. The forall will return true if there is no last element in collected, otherwise if there is, it will return true if the passed in lambda evaluates to true. And in Scala, == invokes .equals (after doing a null check), so you don't need to use .equals in Scala.
So, putting this in a template:
#for(ind <- indicators.foldLeft(Vector.empty[Indicator]) { (collected, next) =>
if (collected.lastOption.forall(_.getFirstFound != next.getFirstFound)) {
collected :+ next
} else {
collected
}
}){
...
}

Connect one observable to another existing one

I have two observables, one that produces elements, other that is a Subject that subscribers are subscribed to. I would like subscribers to get what comes through the first one. One way is to do the following.
first.Subscribe(a => second.OnNext(a);
Somehow I only like to Subscribe at the final end, not to Subscribe just to pipe one to the other. I am curious if there is any Rx extension that allows something like that before I go about writing my own.
This works for me:
var subject = new Subject<long>();
subject.Subscribe(x => Console.WriteLine(x));
var observable = Observable.Interval(TimeSpan.FromSeconds(1.0));
observable.Subscribe(subject);
I get the series of values from the Interval observable from the Console.WriteLine observer.