Search code examples
angularfirebasefirebase-realtime-databasees6-promiseangularfire2

angular firebase handling create flow


I am using angular with firebase realtime DB. I have an app doing payment processing for an order. The current code looks like below

my ionic page .ts is invoked on paynow button as below:

  startPayment(){
        this.instamojoClient = new Instamojo(this.http, this.iab, 'XXX');
        var data = this.instamojoClient.getPaymentFields()

        this.instamojoClient.payNow(data).then(response => {

           //payment is successful now create a order for the customer
           this.ddlSvc.createOrder(this.core.order, this.core.user)
        }).catch(err => {
         console.log("Payment failed: " + JSON.stringify(err))
        });
      }

the createOrder is like below

   createOrder(order:Order, customer:User){
        console.log("new technique to creating new order for #" + order.orderNumber)
        const itemRef = this.db.list('orders')
        const payload = {
          order: order,
          customer: customer
        }

        itemRef.push(payload).then(
          (data) => {
            const orderKey = data.key
             //create a cross entry in the user as well to maintain history
            const userRef = this.db.object('/users/' + customer.uid + "/orders/" + orderKey )
            userRef.set(order)
          }
        )  
      }

I have few questions/problems: 1. startPayment should be able to wait until createOrder is completed so that i can show a message to user for successful process of order. What do i return from createOrder service function to achieve that?

  1. The create order is doing two things: it is creating an order for seller to process and also creating a cross entry against the user who placed the user so that he can see it in his history. Basically an order data is duplicate due to this. Is this the right thing to do? if no then what should i do?

  2. The create order is doing 2 things as mentioned above. How do i handle if first or 2nd operation fails? How do I ensure that I do not end up with corrupted data?


Solution

  • Simply return the promise. In pseudo code:

    startPayment().then()
    
    startPayment(): Promise {
       //...
       return payNow.then(() => {
           return createOrder();
       });
    }
    
    createOrder(): Promise {
        // ...
        return itemRef.push...
    }
    

    However you can make your life easier by using the reactive pattern:

    startPayment.subscribe(() => {
        // success
    }, error => {
       // error
    })
    
    startPayment(): Observable<any> {
        return from(payNow()).pipe(
            switchMap(dataFromPayNow => createOrder(dataFromPayNow))
        );
    }
    
    createOrder(): Observable<any> {
        //...
        return from(itemRef.push()).pipe(
            switchMap(item => {
                return from(userRef.set());
            })
        )
    }
    

    You can use catchError operator to handle errors in the stream.