Skip to main content

Overview

Encore.placement(id).show() returns a Promise<PlacementResult>. You can either await it and branch on the returned value (async-result) or register global onPurchaseRequest / onPassthrough handlers (handler-based). Both work; pick whichever fits the call site. For the cross-platform decision tree, see Integration Patterns.

Async-result pattern

Use this when the component that triggers show() already has access to your purchase + decline logic.

Basic example

From a component

Result type

iOS surfaces granted / not_granted; Android surfaces completed / dismissed / no_offers. Treat both grant cases (granted, completed) as success and the rest as decline. See PlacementResult.

Handler pattern

Use this when show() is invoked from many sites that share post-purchase logic, or when the trigger is far from your billing code.

Register at app startup

You must call Encore.completePurchaseRequest(success) in every code path of onPurchaseRequest. Failing to do so blocks the SDK from presenting future offers. See completePurchaseRequest().

Then show() from anywhere


When to use which

  • Async-result — component already imports your billing client. Branch-specific code lives at the call site.
  • Handler — registered once at app root; many show() sites share the same purchase delegation.
  • Mixed — register handlers for cross-cutting telemetry; still await show() for site-specific UI navigation.
See the decision tree for the full rationale.

Re-registration semantics

Internally, each setter calls currentSubscription?.remove() before adding the new listener — there is no double-fire. The returned unsubscribe function is useful for component lifecycles (call from a useEffect cleanup) but is not required to prevent double-fires when you replace via re-registration.

Platform-specific notes

  • Status values vary by platform — iOS surfaces granted / not_granted; Android surfaces completed / dismissed / no_offers. Code that handles both cases is portable.
  • Event-emitter under the hood — handlers are wired via NativeEventEmitter, but the JS API has replace semantics on the JS side as well. You don’t need to manually remove listeners between re-registrations.
  • completePurchaseRequest is required — unlike iOS / Android native SDKs where onPurchaseRequest simply throws or returns, RN’s bridge needs an explicit ack. Always call it.
  • Provider — wrap your root in <EncoreProvider apiKey="..."> so the bridge is configured before any show() call.

See also