When to use DJISDKManagerDelegate. componentConnectedWithKey or productConnected? - dji-sdk

I am wondering about what the difference in when and how to access a component after a product connected.
One can either wait until
DJISDKManagerDelegate.productConnected and productChanged get called and then access the component
or wait for
DJISDKManagerDelegate.componentConnectedWithKey gets called, check for the key and then get the component from the product.
Can I safely assume, that when a product connected, all its components are connected as well?
Are there any advantages or disadvantages of any of the both methods above? Maybe different use cases?

Related

Best practices in DDD to validate an object

Let's say I have an entity called Order. My Domain must be certain that, as it receives an Order to be included, the Client associated with is active.
What are the best practices to validate that?
In other words, what are the best practices to validate some entity related to the one that is being validated? Where should that validation be called?
Ideally: your decision making (computation, branching, and so on) would be in the domain model. Your retrieval of the information would be in your application code, and your application code would pass the information to the domain model as an argument.
Your domain entity holds its information, and everything else it needs to know gets passed to it.
The life-isn't-always-ideal version: if proactively fetching Client::isActive is expensive, then you probably don't want to always fetch the information. So you either (a) design a protocol such that the domain model tells the application code that it needs this information, and the application code fetches the information and passes it back or (b) you pass to the domain model the capability to look up the information for itself (aka, pass a "domain service" that knows how to fetch the information on demand).
The two approaches have different tradeoffs regarding code complexity, timing, error handling.

What is the best practice to get the required data into VueJS component?

I'm building my first VueJS application which is intended to be used by hundreds of people in the future. I tried to make the individual components reusable and indpendent as possible. To achieve this i decided to let every component fetch its required data themselves. This works fine but i'm not sure if its best practice. I could also pass the data between the components or even using the 2-way data binding functionality.
The sketch bellow describes one of the situations i have. Note that 1 account has 1..* users. As you can see i need to fetch the accounts to display them in the accountOverviewComponent.
Currently i only fetch the accounts in the accountOverviewComponent and fetch the users when the account edit button by the passed accountId in the accountOverviewComponent is clicked. This way i don't fetch data i don't need at the time.
I can also include the users (god knows which data/relations will be added in future) to the fetch account response as wel so i can pass all required data to the accountShowComponent when a account edit button is clicked. This way i can save requests to the server with the side note that i fetch users of accounts i dont need. A possible disadvantage is that the account is updated in the accountShowComponent and not in the accountOverviewComponent (for example when the accountShowComponent is a modal on top of the accountOverviewComponent. So i need to pass the updatet account back or re-fetch the accounts after a save or something.
As third option I can do the same in option 2 but than with the 2-way data binding which handles the data synchronization between the components. This will probably restrict the usage of the accountShowComponent to cases where the accountShowComponent is used "on top" of a parent which contains the data.
I can also store the data in a Vuex store and update the stores all the time. I read that this is bad practive as it should be only used for data which is required accros the SPA. I think Vuex is overkill in "simple" situations like this?
What is the best practice of the described situation? I have a bunch of comparable situations/scenarios in my application. Performance (also for mobile devices), scalability and being "future proof" (extendability/modularity) are important for me. Can someone help me out because i'm a bit lost in the options i have?
UPDATE
The reason i think Vue is overkill is comming from this article which makes totally sense from a software engineer perspective to me (i may be wrong). As my components have a kind of "parent - child" relation so i can solve my "issue" easily with passing data (or use 2-way data binding) and callback-events.
The number one use case for storing data in a centralized store like Vuex, is, because the data must be accessible in multiple places of your application, by components which oftentimes are not related in any way (they neither are parents or children of each other). An example of this would be certain user settings to configure how your application looks or what date format should be used, to name a concrete example.

CQRS DDD: How to validate products existence before adding them to order?

CQRS states: command should not query read side.
Ok. Let's take following example:
The user needs to create orders with order lines, each order line contains product_id, price, quantity.
It sends requests to the server with order information and the list of order lines.
The server (command handler) should not trust the client and needs to validate if provided products (product_ids) exist (otherwise, there will be a lot of garbage).
Since command handler is not allowed to query read side, it should somehow validate this information on the write side.
What we have on the write side: Repositories. In terms of DDD, repositories operate only with Aggregate Roots, the repository can only GET BY ID, and SAVE.
In this case, the only option is to load all product aggregates, one by one (repository has only GET BY ID method).
Note: Event sourcing is used as a persistence, so it would be problematic and not efficient to load multiple aggregates at once to avoid multiple requests to the repository).
What is the best solution for this case?
P.S.: One solution is to redesign UI (more like task based UI), e.g.: User first creates order (with general info), then adds products one by one (each addition separate http request), but still I need to support bulk operations (api for third party applications as an example).
The short answer: pass a domain service (see Evans, chapter 5) to the aggregate along with the other command arguments.
CQRS states: command should not query read side.
That's not an absolute -- there are trade offs involved when you include a query in your command handler; that doesn't mean that you cannot do it.
In domain-driven-design, we have the concept of a domain service, which is a stateless mechanism by which the aggregate can learn information from data outside of its own consistency boundary.
So you can define a service that validates whether or not a product exists, and pass that service to the aggregate as an argument when you add the item. The work of computing whether the product exists would be abstracted behind the service interface.
But what you need to keep in mind is this: products, presumably, are defined outside of the order aggregate. That means that they can be changing concurrently with your check to verify the product_id. From the point of view of correctness, there's no real difference between checking the validity of the product_id in the aggregate, or in the application's command handler, or in the client code. In all three places, the product state that you are validating against can be stale.
Udi Dahan shared an interest observation years ago
A microsecond difference in timing shouldn’t make a difference to core business behaviors.
If the client has validated the data one hundred milliseconds ago when composing the command, and the data was valid them, what should the behavior of the aggregate be?
Think about a command to add a product that is composed concurrently with an order of that same product - should the correctness of the system, from a business perspective, depend on the order that those two commands happen to arrive?
Another thing to keep in mind is that, by introducing this check into your aggregate, you are coupling the ability to change the aggregate to the availability of the domain service. What is supposed to happen if the domain service can't reach the data it needs (because the read model is down, or whatever). Does it block? throw an exception? make a guess? Does this choice ripple back into the design of the aggregate, and so on.

How to handle data composition and retrieval with dependencies in Flux?

I'm trying to figure out what is the best way to handle a quite commons situation in medium complex apps using Flux architecture, how to retrieve data from the server when the models that compose the data have dependencies between them. For example:
An shop web app, has the following models:
Carts (the user can have multiple carts)
Vendors
Products
For each of the models there is an Store associated (CartsStore, VendorsStore, ProductsStore).
Assuming there are too many products and vendors to keep them always loaded, my problem comes when I want to show the list of carts.
I have a hierarchy of React.js components:
CartList.jsx
Cart.jsx
CartItem.jsx
The CartList component is the one who retrieves all the data from the Stores and creates the list of Cart components passing the specific dependencies for each of them. (Carts, Vendors, Products)
Now, if I knew beforehand which products and vendors I needed I would just launch all three requests to the server and use waitFor in the Stores to synch the data if needed. The problem is that until I get the carts and I don't know which vendors or products I need to request to the server.
My current solution is to handle this in the CartList component, in getState I get the Carts, Vendors and Products from each of the Stores, and on _onChange I do the whole flow:
This works for now, but there a few things I don't like:
1) The flow seems a bit brittle to me, specially because the component is listening to 3 stores but there is only entry point to trigger "something has changed in the data event", so I'm not able to distinguish what exactly has changed and react properly.
2) When the component is triggering some of the nested dependencies, it cannot create any action, because is in the _onChange method, which is considering as still handling the previous action. Flux doesn't like that and triggers an "Cannot dispatch in the middle of a dispatch.", which means that I cannot trigger any action until the whole process is finished.
3) Because of the only entry point is quite tricky to react to errors.
So, an alternative solution I'm thinking about is to have the "model composition" logic in the call to the API, having a wrapper model (CartList) that contains all 3 models needed, and storing that on a Store, which would only be notified when the whole object is assembled. The problem with that is to react to changes in one of the sub models coming from outside.
Has anyone figured out a nice way to handle data composition situations?
Not sure if it's possible in your application, or the right way, but I had a similar scenario and we ended up doing a pseudo implementation of Relay/GraphQL that basically gives you the whole tree on each request. If there's lots of data, it can be hard, but we just figured out the dependencies etc on the server side, and then returned it in a nice hierarchical format so the React components had everything they needed up to the level where the call came from.
Like I said, depending on details this might not be feasible, but we found it a lot easier to sort out these dependencies server-side with stuff like SQL/Java available rather than, like you mentioned, making lots of async calls and messing with the stores.

How to avoid action chains

I'm trying to understand Flux pattern.
I believe that in any good design the app should consist of relatively independent and universal (and thus reusable) components glued together by specific application logic.
In Flux there are domain-specific Stores encapsulating data and domain logic. These could be possibly reused in another application for the same domain.
I assume there should also be application-specific Store(s) holding app state and logic. This is the glue.
Now, I try to apply this to imaginary "GPS Tracker" app:
...
When a user clicks [Stop Tracking] button, corresponding ViewController raises STOP_CLICK.
AppState.on(STOP_CLICK):
dispatch(STOP_GEOLOCATION)
dispatch(STOP_TRACKING)
GeolocationService.on(STOP_GEOLOCATION):
stopGPS(); this.on = false; emit('change')
TrackStore.on(STOP_TRACKING):
saveTrack(); calcStatistics(); this.tracking = false; emit('change')
dispatch(START_UPLOAD)
So, I've got an event snowball.
It is said that in Flux one Action should not raise another.
But I do not understand how this could be done.
I think user actions can't go directly to domain Stores as these should be UI-agnostic.
Rather, AppState (or wherever the app logic lives) should translate user actions into domain actions.
How to redesign this the Flux way?
Where should application logic go?
Is that correct to try to keep domain Stores independent of the app logic?
Where is the place for "services"?
Thank you.
All of the application logic should live in the stores. They decide how they should respond to a particular action, if at all.
Stores have no setters. The only way into the stores is via a dispatched action, through the callback the store registered with the dispatcher.
Actions are not setters. Try not to think of them as such. Actions should simply report on something that happened in the real world: the user interacted with the UI in a certain way, the server responded in a certain way, etc.
This looks a lot like setter-thinking to me:
dispatch(STOP_GEOLOCATION)
dispatch(STOP_TRACKING)
Instead, dispatch the thing that actually happened: STOP_TRACKING_BUTTON_CLICKED (or TRACKING_STOPPED, if you want to be UI-agnostic). And then let the stores figure out what to do about it. All the stores will receive that action, and they can all respond to it, if needed. The code you have responding to two different actions should be responding to the same action.
Often, when we find that we want dispatch within a dispatch, we simply need to back up to the original thing that happened and make the entire application respond to that.

Resources