Apologies if this question has been answered elsewhere, I attempted to search for it but I'm not exactly sure what I should be looking for.
Imagine I have this complex object:
userRequest: {
id: number,
subject: string,
...
orderIds: number[]
...
}
order: {
id: number,
...
clientId: number,
productIds: number[]
}
client: {
id: number,
name: string,
...
}
product: {
id: number,
name: string,
price: number
}
At some point, the user will fill out a form using this composite object and submit it for analysis. However, before submission, the data must be validated. Since the user is inputting data received on paper, a request for more information may be necessary if the data is deemed "invalid."
Therefore, validation is required for the request, orders, products, and client. The process involves displaying a "Validating Request" screen and subsequently showing a "Valid" or "Invalid" screen after checking each element.
The challenge arises when handling http requests and Observables. While attempting to understand various operators and their combinations, I find myself completely lost.
Essentially, I receive an Observable<userRequest>
from the server initially. Subsequently, upon receiving a userRequest, I need to retrieve all corresponding orders by their IDs. Following this, I must obtain the client and their associated products once an order is obtained.
All these actions occur asynchronously, with dependencies between elements - such as not being able to fetch the client or products until the order is received, and requiring the userRequest for obtaining the orders. Moreover, acquiring both the client and products simultaneously poses further complexity due to their shared dependence on the order. Finally, validation is required for every element (request, order, client, product) before determining the overall validity of the request.
In summary:
- I must acquire an
Observable<userRequest>
and validate it - Next, I need to acquire an
Observable<order[]>
and validate each individual order - For each order:
a) Obtain an
Observable<Client>
and validate it b) Get anObservable<Product[]>
and validate each product - Await completion of all Observables and check for overall validity
Steps 1 and 2 are executed sequentially, whereas step 3.1 and 3.2 are triggered after completing step 2. All subsequent steps must also adhere to this sequential processing.
Although I have a general idea of what needs to be done, I struggle with chaining Observables in a sequential manner due to dependencies. Especially challenging is coordinating validations for the Client and Products that both require the Order ID. Despite numerous attempts, I am unable to grasp the concept entirely.
bygrace - No, I do not intend for validation to block the process. Validation should occur smoothly without hindering the flow, leading to requests for any missing or invalid components which can be displayed at the end. Therefore, I seek a way to determine when all elements have been successfully processed so I can identify any errors present.
The methods for retrieving the request, orders, clients, and products are encapsulated within their respective services which make http requests and return Observables. Thus, synchronizing these calls, especially in the case of Orders where two Observables are needed for the same Order ID, presents a significant challenge.
QuietOran - Below is a snippet of my attempt to solve this issue. However, I acknowledge its shortcomings and recognize that I am currently lost...
onValidateRequest(requestId: number) {
this.requestService.getUserRequest$(this.requestId)
.do(request => {
this.validateRequest(request);
})
.concatMap(request => this.orderService.getOrdersForRequest$(request.id))
.do(orders => {
this.validateOrders(orders);
})
.concatMap(orders => {
// This section where I get completely stuck
// Successfully retrieved the request and orders, however, struggling to obtain the client AND products here
// Need to validate each one upon receiving them
// Then return something
})
.do(() => {
// When validating an element, any errors encountered are added to an array
// Upon completion of all above Observables, this function checks for errors
this.checkForErrors();
})
.subscribe();
}