Scenario: Two Logic Apps. We'll call them Parent and Child.
Use Case:
- Parent prepares a request for Child.
- Parent invokes Child with request data.
- Child has schema defined on Request trigger.
- Child sends data received from Parent to an external API endpoint and gets the response, returning it as a Response action.
Issue:
When calling Child using the Logic App action, each non-nullable parameter is there in the designer for Parent based on JSON schema in Child. However, the output of that Logic App action is just a Body, no Status Code.
When calling Child using POST endpoint URL from Child Request action, parameters are not visible so we have to compose the request, but Status Code is returned and accessible.
Question:
Is there a way using the Logic App Action (first screenshot) to get the Status Code or must we use the HTTP request version?
Is there a way using Logic App action to specify values for the nullable parameters in the JSON schema?
If the answer is HTTP request version, how do we best define the URL so that it remains consistent between environments? DNS? APIM?
I found what appears to be the only solution to this. It is rather counter-intuitive as it would seem a Logic App action should expose a statusCode output by default along with the body. But it doesn't.
In the parent Logic App which consumes the child Logic App, to get the status code returned by the child, you can initialize a variable following this pattern for the expression
outputs('<action-name>')['statusCode']
After you save, the designer makes it look like a first-class dynamic content variable even though it is not directly accessible in the dynamic content list, regardless of your variable type for some reason.
Related
I have a parent component with a button that when clicked launches a modal window child component. A request is made from the child component when it first renders, and then response data is saved to local state, e.g.
useEffect(() => {
const response = await getData(id);
setData(response.data)
...
}, []);
In the parent component I am testing if the modal window launches - to do this I can just test that the dom element is present after the button is clicked, great. However when the modal window launches the request is made from the child component resulting in the error:
Error: connect ECONNREFUSED 127.0.0.1:80
There seem to be two options:
1/ Use msw to provide a mock endpoint for the request. However due to the state being updated it results in the following error:
Warning: An update to Component inside a test was not wrapped in act(...)
2/ Mock the entire child component using jest.mock(). This is the logical thing to do as I am testing the parent component and I do not care about the child. However from what I have read this is not the RTL way of doing things.
This seems like it must really common testing scenario, but I haven't found a solution so any advice on the best way to do this would be appreciated.
In this scenario it seems the best option is just to simply mock the child component with Jest as we do not care about it's internals, even though this goes against RTL's best practises.
Stub data from requests to 3rd parties if your writing good tests, i.e. data your child is getting... or if you strictly unit testing then mock the child.
Depends on the type of test you want. Sandi Metz has a nice clear why of explaining what you should be testing. I don't like the mock the child approach as it leads to fragile tests - better to test behaviour i.e. that data back from your stub has been saved to state / updated somewhere.
edit: mock the child component and set an expectation that it receives a query/command, or pivot to testing the child and setup mock state of the parent.
Is there any mechanism to determine completion of child component rendering, which is having Ajax call in it from parent component.
For below example, i am collection some IDs inside User component with Ajax call. On completion of all User calls i need to fire another AJAX call to get info by collected IDs from earlier request.
{
Users.map((user,i)=>{
return <User key={i} user={user} /> //has a ajax call.
});
//Do something with collected IDs.
}
React has unidirectional data flow where children listen to changes from parent. If you need the reverse to happen, you need to provide a method which can be called from User once its load completes :
Users.map((user,i)=>{
return <User key={i} user={user} onLoad={handleLoad} /> //has a ajax call.
});
Like this you can track the load status of each User, but this is considered anti-pattern as multiple components are handling the same operation and separation of concern goes for a toss.
Instead make the required fetch in your main component itself, and provide the data to User making it completely pure component.
You should use promises coupled with an event handler as a prop
I would argue that the ajax call should not be in the child component.
The parent already has an array of users. So it could easily make the call.
That would vastly reduce the complexity of your problem.
Is there any good reason why the child needs to make the call?
Here is your other option:
You need to debounce the 'final' ajax call. AND keep a record of all the existing data with a callBack and some local state;
Here is a sandbox solving your problem with the latest and greatest hooks.
https://codesandbox.io/s/keen-hellman-mhc22
You can load the data in a data loader component, and then create the component with the data prop
I have a bunch of hierarchically arranged components, namely:
partner component, that works with partner organizations, knows how to update or remove them, etc.;
leader component, that works with leader organizations, knows how to deal with leader organizations;
list component, than displays to the user both partner and leader organizations;
a service - when partner or leader components removes an organization, info on this organization is passed to the list component so that these changes are reflected in front immediately.
I cannot provide code samples on this, it's too big, moreover my question mostly requires a conceptual advice rather than code issues.
Right at the moment it perfectly works - components are doing their job sending data to the service:
IndexCollection.setIndexes(
vm.leaderIndex, vm.partnerIndex, 'added_l', response.id
);
the service does it's job and pushed changes to a variable, which I $watch in the list component to trigger respective actions like this:
$scope.$watch(() => IndexCollection.indexes, function() {
let indexes = IndexCollection.indexes;
switch (indexes.message) {
case 'deleted_p':
removePartner(indexes);
break;
case 'deleted_l':
removeLeader(indexes);
break;
case 'added_l':
addLeader(indexes);
break;
}
});
My question is of a more theoretical essence. Is there a possibility to trigger real-time actions from service in the list component without using$watch, $emit, $broadcast and other standard tools we usually use in this regard?
Can I somehow achieve the same result by means of using callbacks? I mean, when a change in service occurs, it triggers immediate action in the respective controller?
While using $watch may solve the problem, it is not the most efficient solution.
You might want to change the way you update and retrieve the data of your service.
The component controllers should manipulate the data stored in your service with functions in your service based on actions/events triggered from your component and you inject the service in the component.
MyDataService.getIndexCollection() {}
MyDataService.putIndexCollection() {}
Then you pass the data down to all your directives and components via require or bindings for components or isolated scopes for your directives.
For example once the partner components edits the data on the service you fetch the data again from your service and the updated data will be passed to your list component and update the view via $apply() if needed.
Application data lives in stores
Application (ui) state lives in stores (there are different opinions tho)
When the user now submits a form and the server returns a validation error, hot do I get this error back to the view component (the form)? Since the (controller) view components only gets updated by change events from the store(s), the error would need to be added to a store. Other people say that in those cases the view components should be able to listen to events from the action creators.
Whats your opinion on that?
Possibly a duplicate of How to handle async errors in Flux?
In the case where the error doesn't really matter to the rest of the app and you don't need to log it, I'd just return the value right to the component. For example, say you're submitting a form and it comes back 422 or something...unless you want to do something with the error like store it, and none of the other components really care that it errors, don't worry about it...just update the state of the View Component.
Although generally speaking it's best to have state at the top most component, it makes sense for some components (like forms) to have a "transient" state that only matters to them...for example when you're typing in text to a box there's no reason to bubble that up to the top-level component usually.
I'm trying to wrap my head around Facebook's Flux...
Say I have an app with a side menu that can be hidden and shown via a button in the header.
My header is one component, my side menu is another component.
Currently my Header component just sets a class on the HTML div side menu element which gets animated to hidden by CSS.
What's the general idea here?
ReactJs doesn't really care about how it gets its data (how it's data is getting passed in or how that data should be handled across the web application). That's where Flux comes in, it creates a functional approach on how data is handled. Data-flow is essentially:
Action -> Data Store -> Component
Mutation of data happen through calling Actions. The Data Stores themselves have to listen on the actions and mutate the data within the store. This keeps the data structure and logic flat.
In your case, your dataflow would probably look something like this:
Header --> User Click --> Fires action --> Updates store --> Side menu listening and responding to that store change.
Your case is a simple example which you probably don't really need Flux. I think it's easier if you have a parent component that maintains the view state logic, and use props/callbacks for the 2 children components (side menu and header). But a more advanced example that you need to make ajax calls and maintain session, Flux would become useful. Like if you have a Login Component, and you want to show different side-menu options and header options depending on user:
Login Component --> User Logins --> Calls Action #signIn --> Showing Loading State
--> Dispatcher handles action (make api call to authenticate user and load user data)
On success (for the api call), alert sessionStore, and populate store with data
On error, maybe fire another action that says login failed or something
SessionStore ---> Header Component (Listens to Store) --> Update view based on store information
---> Side Menu Component (Listens to Store) --> Update
speaking more general:
flux is a software architecture for a unidirectional Dataflow. It's Chain is Action -> Delegation -> Store -> View... The action - for example a Button Click - gets delegated to stores where your applicationlogic and data is kept... here your action and data will be changed and processed. The store eventually emits an event which views (for example react components) previously registered on with a callback. In this callback you can GET your data from your stores. It is important to mention that you can only access the stores READ-Only.
So for your case... if you want component A to affect component B you will have to register component B to the store eventEmitter and GET the desired data from the store. Once component a triggers an action it gets delegated to the store, your functions are performed and eventually the event gets thrown that starts component B's callback.
Hope this got clear enough... its way cooler with some nice drawings.