Angular: data reuse priniciples vs making server calls - angularjs

I am struggling with figuring out some of the data reuse principles using Angular and Web Api.
Let's have an example. I am creating an administrative website of CRUD forms.
Objects: Specializations (parent) Name (string, child of
specialization) Description (string, , child of specialization)
Requirements(collection, child of specialization)
Challenges(collection, child of specialization) ChallengeName (string,
child of Challenges) StartDate(Date, child of Challenges)
Activities(collection, child of Challenges)
On the main page I will make a call to GetAllSpecializations and list them. On this page you might have 3 challenges associated to that Specialization.
I will select one of the challenges to get details about that challenge. At this point would I query the client side object made in the initial GetAllSpecializations service call? Or would I need to make a separate call to GetSpecialization(id) API call.
The latter is a typical way of doing things but was thinking there was some data reuse that can happen across CRUD views without make calls to get all the details on each view.
Thanks for any clarification on best practices.

That all depends on size of your data in the initial call. If it is static, not more than few KBs and you are not worried about the initial response tine, you can fetch all records and store it in scope.
Then you can show/hide the data as needed.
Calling service for each individual item will be of course fast because of less response data but it will increase number of service call hence network traffic.
First approach will always be good although it takes slightly more time in page load but subsequent requests are served immediately.

Related

Will rendering multiple views in Backbone happen synchronous or asynchronous?

Let me start by saying this is a theoretical question thus I cannot provide you with any code.
I'm thinking about a Backbone structure where multiple views get rendered on one page. Every view contains a render function with one or more API calls which have responsetimes that can be fast or slow.
I'm wondering if we have view order A, B, C, D and A's data is responding slowly from the server, will this block the rendering/data retrieval of B, C and D when I loop through those views to render, or will it initialize the render function of A don't care about it and initialize the render function B?
I tried to write this as clearly as possible but if you have any questions just ask.
UPDATE: Some time passed and I found a way to link these all together. I worked with a jQuery deferred and used the pipe method to pipe these deferreds together. Source: https://api.jquery.com/deferred.pipe/
I tested this by setting up a JSFiddle and found out that Backbone doesn't care about loading slow requests. It just renders another view if that's called. For anyone's information
Pull in external resources
Build two views where one has a call to a large data end point

Coalescing Flux Actions

This is a detailed Flux Architecture question.
Say I have a resource that gets asynchronously prepared. Let's take User Data as an example.
There are multiple different ways to get this user data - in our example it may be that it requires a few different subsequent queries to generate from the server or is stored locally as a whole.
Case 1:
User data needs sequential steps. Fire USER_DATA_1_SUCESS, USER_DATA_2_SUCCESS. Other stores listen for USER_DATA_2_SUCCESS.
Case 2:
User Data is locally available as a whole. Fire a USER_DATA_READY action.
I'm trying to figure out how to go from a linear state completion (USER_DATA_2_SUCESS) to a resource ready event (USER_DATA_READY) in the stores. I can't call USER_DATA_READY directly from the stores - I get a can't call action in the middle of dispatch error. At the same time I want granularity - I want to control the different stages of putting the data together.
I'd like to have one way to condense these calls with good design. The option I can think of is:
Add a convenience 'Ready' function in a client class that is visible to the store. Call it with a tiny timeout in the stores callback for USER_DATA_2_SUCCESS.
Can anyone suggest a better flow?

Multiple Components Using One Store

What's the best way to handle a case where multiple components are using one store (which is populated by API calls in an action creator), but each component may need to access different sets of data without effecting the other. I.e.: two table components display data from the WidgetStore; one table wants all widgets, the other only displays widgets whose name contains "foo" (this would be based on user input). The table being queried via the API has tens of thousands of widgets, so loading them all into the store and filtering from the store isn't practical. Is there a Flux architecture (like Redux) that already has a way of handling this type of thing?
The simplest way is to just create a parent component and selectively hand off data, using a pluck or selector function, to each of the children.
For the more general answer for yourself going forward... if you follow something along the lines like redux there is already proven patterns which will help you understand passing complex data down.

In flux, why Store is needed?

According to Flux Architecture View uses Action to call Dispatcher that updates the Store, while View listening to Store change events.
My question is: Why do we need Store?
In order to list all users, my Component will call ListAllUsersAction that will in turn call my API and will update the Store with the result of API call. Store then emits change event that the View is listening to. But the store also stores the result. Why? Why this middle layer is needed? I wont call the store directly anyway, so this cache layer makes no sense to me, and as I generate more events that loads more data, eventually all my stores will have all the state of my application because flux architecture says nothing about cleaning the Stores.
Am I missing something?
The goal of Flux is to keep data flow easy to understand even as apps becomes large and complex, such that a new person can be brought up to speed quickly, figure out what's going on by inspecting the source code, and be confident that they can make changes without breaking things. Modularity and separation of concerns are a big part of that. The Stores are a way to keep the data models independent of the details of the view layer and establish a single source of truth for the application state. You can look at any Store's code and see what data it holds, what actions it responds to, which dependencies it has for data in other Stores. It's a matter of organization for the sake of the developers, at the cost of code being slightly less compact.
In order to list all users, my Component will call ListAllUsersAction
that will in turn call my API and will update the Store with the
result of API call.
Since the function of Actions is mainly to provide updated data to stores, you could also just call the API first and then just create one Action to handle the result.
as I generate more events that loads more data, eventually all my
stores will have all the state of my application because flux
architecture says nothing about cleaning the Stores.
Holding the current state of the application is the intended function of the Stores. If user actions or API calls cause the data to change, the Actions notify the Stores and the Stores responsible for keeping that data update accordingly (maybe even being reset to null). There's no need for any other sort of cleaning, because the Stores "having all the state" is exactly what they're supposed to be doing.
Stores are in charge of application state and logic, so for example, let's say you fetch all users through your ListAllUsersAction, you get an array from your API
var users = [{firstName: 'LIMELIGHTS'}, {firstName: 'SKWEE357'}];
Now, the users name are apparently capitalised as your API decides that this is the way to deliver the data.
This just won't do so you want to fix it.
Using just React or just the Action where would you put this code, where would it make sense?
In your view, your dispatcher or your action? No, you definitely don't want to clutter your React component with this type of logic.
Nor does it make sense to do this data manipulation in the Dispatcher or Action, they are after all just notifiers that something should happen.

Why should I use Actions in Flux?

An application that I develop was initially built with Flux.
However, over time the application became harder to maintain. There was a very large number of actions. And usually one action is only listened to in one place (store).
Actions make it possible to not write all event handler code in one place. So instead of this:
store.handleMyAction('ha')
another.handleMyAction('ha')
yetAnotherStore.handleMyAction('ha')
I can write:
actions.myAction('ha')
But I never use actions that way. I am almost sure, that this isn't an issue of my application.
Every time I call an action, I could have just called store.onSmthHappen instead of action.smthHappen.
Of course there are exceptions, when one action is processed in several places. But when that happens it feels like something went wrong.
How about if instead of calling actions I call methods directly from the store? Will my application not be so flexible? No! Occurs just rename (with rare exceptions). But at what cost! It becomes much harder to understand what is happening in the application with all these actions. Each time, when tracking the processing of complex action, I have to find in stores where they are processed. Then in these Stores I should find the logic that calls another action. Etcetera.
Now I come to my solution:
There are controllers that calls methods from stores directly. All logic to how handle action is in the Store. Also Stores calls to WebAPI (as usually one store relating to one WebAPI). If the event should be processed in several Stores (usually sequentially), then the controller handles this by orchestrating promises returned from stores. Some of sequentials (common used) in private methods of itself. And method of controllers can use them as simple part of handling. So I will never be duplicating code.
Controller methods do not return anything (one-way flow).
In fact the controller does not contain the logic of how to process the data. It's only points where, and in what sequence.
You can see almost the complete picture of the data processing in the Store. There is no logic in stores about how to interact with another stores (with flux it's like a many-to-many relation but just through actions). Now the store is a highly cohesive module that is responsible only for the logic of domain model (collection).
The main (in my opinion) advantages of flux are still here.
As a result, there are Stores, which are the only true source of the data. Components can subscribe to the Stores. And the components calls the same methods as before, but instead of actions uses controller. Interaction with React did not change at all.
Also, event processing becomes much obvious. Now I can just look at the handler in the controller and all becomes clear, and it's much easier to debug.
The question is:
Why were actions created in flux? And what are their advantages that I have missed?
Actions where implemented to capture a certain interaction on the view or from the server which can then be dispatched to as many different stores as you like. The developers explained this with the example of the facebookchat.
There is a messageStore and a threadstore. When the action eg. messagePost was emitted it got dispatched into both stores doing different work to update their attributes. Threadstore increased the number of unread messages and messageStore added the new message to its messagearray.
So its basicly channeling one action to perform datachanges in more than one store.
I had the same questions and thought process as you, and now I started using Flummox which makes it cleaner to have the Flux architecture.
I define my Actions in the same file where I define my Store, and that's close enough. I can still subscribe to the dispatcher to log events so I can see all actions being called, and I have the option to create multi-store Actions if needed.
It comes with a nice FluxComponent that lets you wrap all store-related code in a single place so its children are stateless components that get updated on store changes, like
<FluxComponent connectToStores={['storeA', 'storeB']}>
<InnerComponent />
</FluxComponent>
Keeping the Flux architecture (it uses Facebook's Flux behind the scenes) will hopefully make it easy to use other technologies like GraphQL.

Resources