Bind to IReactiveCommand in view code behind - viewmodel

I have my ViewModel which has an ErrorCommand. I wish to subscribe to this in my view code behind so that any time it is called I can display an error message which is passed like so:
ErrorCommand.Exectute("Error occured")
In the view:
this.WhenAny(view => x.ViewModel.ErrorCommand, x => x.Value).Subscribe(error => DisplayError(error));
This code doesn't actually work but hopefully shows what I'm trying to acheive. How would I do this correctly?
I understand I could use the MessageBus, but I also have a similar scenario where the MessageBus wouldn't be appropriate.

There's a method specifically for this scenario:
this.WhenAnyObservable(x => x.ViewModel.ErrorCommand).Subscribe(x => /* ... */);
will do what you expect and will avoid the null refs

this.WhenAny(view => x.ViewModel.ErrorCommand, x => x.Value).Subscribe(error => DisplayError(error));
Will only fire when you change the value of the ErrorCommand property.
What you want is this:
ViewModel.ErrorCommand.IsExecuting.Subscribe(x=> DisplayError(x));

Related

Bypass activity output to activity in switch case

I like the idea of activity inputs and outputs and prefer them over setting values in the workflow context. However I am now stuck with this approach when using switch cases. My workflow looks like this:
builder
.ReceiveHttpPostRequest<ImportProducts>("/import")
.Then<ExtractHttpRequestBodyActivity>()
.Then<GetShopDataActivity>()
.Switch(cases => cases
.Add(
context => context.GetInput<ShopData>()!.ShopType == "ShopType1",
#case => #case
.Then<GetShopType1ProductsActivity>()
.Then<FilterShopType1ProductsActivity>()
.Then<ConvertShopType1ProductsActivity>()))
.Then<DebugActivity>();
Without the switch case the input of GetShopType1ProductsActivity is the output of GetShopDataActivity, but using switch case the input is null.
Is there a way to bypass the output to the first activity of the case?
Edit: I'm using Elsa 2.0.0-preview7.1545
There is no way to bypass Elsa form sending activity output automatically to another activity as input.
That being said, it is up to you whether or not you use output/input.
What you can do is this:
Specify a name for GetShopDataActivity (using .WithName). E.g. "GetShopDataActivity1"
Use the output of GetShopDataActivity Directly as input for GetShopType1ProductsActivity.
To use output from a named activity, use the following code:
context.GetOutputFrom<ShopData>("GetShopDataActivity1");
An alternative approach is to store the output from GetShopDataActivity in a variable, then you can use that variable from other activities.
Tip: when developing custom activities, try to expose their inputs. For example, if the GetShopType1ProductsActivity needs the output from GetShopDataActivity, instead of reading input directly from the activity context within that activity, consider exposing the necessary data using an "input" property, like so:
[ActivityInput] public ShopData ShopData { get; set; }
Then you can update your workflow as follows:
builder
.ReceiveHttpPostRequest<ImportProducts>("/import")
.Then<ExtractHttpRequestBodyActivity>()
.Then<GetShopDataActivity>().WithName("GetShopDataActivity1")
.Switch(cases => cases
.Add(
context => context.GetInput<ShopData>()!.ShopType == "ShopType1",
#case => #case
.Then<GetShopType1ProductsActivity>(a => a.Set(x => x.ShopData, context => context.GetOutputFrom<ShopData>(""GetShopDataActivity1)))
.Then<FilterShopType1ProductsActivity>()
.Then<ConvertShopType1ProductsActivity>()))
.Then<DebugActivity>();
This could be cleaned up a bit by adding a couple of extension methods on your GetShopType1ProductsActivity class (more specifically, on ISetupActivity<GetShopType1ProductsActivity> called e.g. WithShopData.
Additionally, if you need the output from GetShopDataActivity in multiple places (like you do already in at least two places), consider creating a an extension method that provides this information.
For example:
public static class ShoppingWorkflowExtensions
{
public static ShopData GetShopData(this ActivityExecutionContext context) => context => context.GetOutputFrom<ShopData>(""GetShopDataActivity1)!;
}
You could then update your workflow like this:
builder
.ReceiveHttpPostRequest<ImportProducts>("/import")
.Then<ExtractHttpRequestBodyActivity>()
.Then<GetShopDataActivity>().WithName("GetShopDataActivity1")
.Switch(cases => cases
.Add(
context => context.GetShopData().ShopType == "ShopType1",
#case => #case
.Then<GetShopType1ProductsActivity>(x => x.WithShopData(context => context.GetShopData()))
.Then<FilterShopType1ProductsActivity>()
.Then<ConvertShopType1ProductsActivity>()))
.Then<DebugActivity>();

NGXS Continuous Triggered Effects

Im trying to create a sample perhaps we switch to NGXS from angular redux + redux-observable.
We do have several usages which starts running based on an action and stop when something else happens running, which I'm not 100% sure how they should be handled. Small scenario:
on connect => listen to heroChanges
on disconnect => unsubscribe
#Action(HeroRealtimeActions.Connect)
heroChanged(ctx: StateContext<HeroRealtimeStateModel>) {
return this.hubClient.heroChanged$().pipe(
// tap(x => console.warn(">>>> hero changed", x)),
mergeMap(heroes => ctx.dispatch(new HeroActions.Update(hero))),
);
}
This is how i want it to work:
Connect completes and not block it e.g. returning Observable it will not complete (as above)
takeUntil on disconnect
cancel/ignore if connect is triggered again e.g. ala switchMap
The above works good however I dont want to block the Connect.
In redux-observable we use to have something as following:
action$ => action$.pipe(
ofType(HeroRealtimeActions.connectSuccess),
switchMap(hubConnection => this.hubClient.heroChanged$().pipe(
// do something...
takeUntil(action$.pipe(ofType(HeroRealtimeActions.disconnectSuccess))),
ignoreElements(),
))
);
Another option I was thinking is using manually .subscribe() use actions$ to takeUntil, but will need something else for switchMap - but it sounds it will get a bit messy
I can easily get something half baked working, I'm more asking for a correct way of doing it
So I believe the most equivalent and also quite clean is to use the ActionHandlers as described here https://www.ngxs.io/advanced/action-handlers. Changed the above as following:
actions$.pipe(
ofActionSuccessful(HeroRealtimeActions.Connect),
switchMap(() => this.hubClient.heroChanged$().pipe(
// tap(x => console.warn(">>>> hero changed", x)),
mergeMap(hero => store.dispatch(new HeroActions.Update(hero))),
takeUntil(actions$.pipe(ofActionSuccessful(HeroRealtimeActions.Disconnect))),
)),
).subscribe();

UpdateOrCreate not working has expected

im trying to user the method "updateOrCreate", and works almost has expected but with a problem.
For example if the record doesnt exists it creates, untill now great, but for example if i change a value in my case the "mybankroll" value it creates another record. I can that understand that is creating because one of the columns record value doesnt exist, but i dont understand how the update actions is fired.
My code example:
UserBankroll::updateOrCreate(
['my_bankroll' => $request->mybankroll, 'currency' => 'EUR'],
['user_id' => Auth::user()->id]
);
But if i try to update the value of my_bankroll, instead of updating it created another record.
You seem to have your arrays backwards.
The first array should be what you are matching against, the second array should be the update values.
https://laravel.com/api/5.0/Illuminate/Database/Eloquent/Model.html#method_updateOrCreate
UserBankroll::updateOrCreate(
['user_id' => Auth::user()->id],
['my_bankroll' => $request->mybankroll, 'currency' => 'EUR']
);

Unit Testing JSON responses in Laravel

I do:
$this->post('/v1/customer', ['area' => 'kil'])
->seeJson(['created' => true]);
But instead of created => true, I would like to do "NOT STATEMENTS".
Ex: parent!=null or created_at > '0000-00-00'
How can this be achieved?
Laravel does have a dontSeeJson function which would solve both of the examples you've listed (though possibly not a more general case) --
$this->dontSeeJson(['parent' => null]);
$this->dontSeeJson(['created_at' => '0000-00-00']);
If you need something more specific, I agree with #gontrollez - decode the json (json_decode($this->response->getContent(), true)) and test that.

Problems querying Factual API data using Ruby wrapper

Trying to implement Factual API with provided Ruby wrapper. Looking to return all Bars within certain number of meters of a geo point. My query looks like this:
factual.table("places").search("category_id"=>"312").geo("$circle" => {"$center" => [40.7811, -73.98], "$meters" => 10000}).rows
This returns a 200:OK response, but 0 records (even though that location is in Manhattan). I'm pretty sure there's a problem with the way I'm passing in the category info.
Per the API documentation, I've also tried passing the category data like this, which returns a syntax error:
factual.table("places").filters("category_ids" => {"category_ids":["6"]}).geo("$circle" => {"$center" => [40.7811, -73.98], "$meters" => 10000}).rows
and this, which returns the Factual error *references unknown field category_ids*:
factual.table("places").filters("category_ids" => {"$in" => ["312", "338"]}).geo("$circle" => {"$center" => [40.7811, -73.98], "$meters" => 10000}).rows
I'm following the documentation samples here and using v3: https://github.com/Factual/factual-ruby-driver/wiki/Read-API and here: http://developer.factual.com/display/docs/Places+API+-+Global+Place+Attributes
EDIT:
I've also tried changing the filters method to search like this:
factual.table("places").search("category_ids" => {"$in" => ["312", "338"]}).geo("$circle" => {"$center" => [40.7811, -73.98], "$meters" => 10000}).rows
This returns records with 338 in the address, irrespective of category. Very strange. I've been trying different things for hours. I'm pretty sure it's an issue with how I'm passing in category information. I'm following the docs as closely as I can, but I can't get it to work.
Try this
factual.table("places").filters("category" => "Bars")
.geo("$circle" => {"$center" =>[40.7811, -73.98] , "$meters" => 1000}).rows

Resources