DEV Community

Cover image for Network Request Callback Toast Issue, Popup Problem, Disable Popup Return
kouwei qing
kouwei qing

Posted on

Network Request Callback Toast Issue, Popup Problem, Disable Popup Return

[Daily HarmonyOS Knowledge] Network Request Callback Toast Issue, Popup Problem, Disable Popup Return, Navigation Foldable Screen Missing Back Button, Responsive Layout

1. HarmonyOS HTTP request callback causes showToast error?

When using http.HttpRequest.request to initiate an HTTP request, executing a custom callback function in the promise's then callback may result in an error when calling toast: [ArkRuntime Log] Error: Internal error. UI execution context not found.

Steps to reproduce:

  1. Create a request with http.createHttp();
  2. Initiate the request with request.request;
  3. Process data in promise.then and execute the callback function
  4. Use promptAction.showToast in the callback function to display the toast

Solution:

The error Internal error. UI execution context not found. occurs because the promptAction.showToast interface detects a missing UI instance in the scenario and throws an exception. Bind the UI instance to call the interface and use proper try-catch for exception handling.

@Entry
@Component
struct Index {
  @State message: string = 'Obtain the UI instance from the window instance and use the interface through the UI instance';

  aboutToAppear(): void {
    setTimeout(() => {
      // Exception capture
      try {
        this.getUIContext().getPromptAction().showToast({ message: 'Popup test', duration: 2000 })
      } catch (e) {
        console.error("Popup exception, error message:" + JSON.stringify(e))
      }
    }, 1000)
  }

  build() {
    Column() {
      Text(this.message)
        .id('HelloWorld')
        .fontSize(15)
        .fontWeight(FontWeight.Bold)
        .textAlign(TextAlign.Center)
        .width('100%')
    }.width('100%')
  }
}
Enter fullscreen mode Exit fullscreen mode

2. How to dynamically display content in a custom component bound to a HarmonyOS Button via bindPopup based on external variables?

Since components within bindPopup are not @component subcomponents, declarative variables like @state and @link cannot be used for passing and updating. Use AppStorage to create or update properties (e.g., whether a favorite is public), and synchronize updates in bindPopup via @StorageLink.

Demo:

export enum PopoverItemType {
  Default,
  AddVideo,
  ManageVideo,
  ModifyName,
  ModifyPrivacy,
  DeleteFolder
}

export interface PopoverItem {
  title: string
  type: PopoverItemType
}


@Component
export struct CollectionManageMenu {
  @State popoverItemList1: PopoverItem[] = []
  @State popoverItemList2: PopoverItem[] = []
  @StorageLink('pub') pub: string = '0'


  aboutToAppear(): void {
    this.popoverItemList1 = [
      {
        title: 'Add Video',
        type: PopoverItemType.AddVideo
      },
      {
        title: 'Batch Manage Videos',
        type: PopoverItemType.ManageVideo
      },
      {
        title: 'Modify Name',
        type: PopoverItemType.ModifyName
      },
      {
        // TODO: The copy should change dynamically based on the status
        title: 'Set as Private',
        type: PopoverItemType.ModifyPrivacy
      },
      {
        title: 'Delete Favorite',
        type: PopoverItemType.DeleteFolder
      }
    ]

    this.popoverItemList2 = [
      {
        title: 'Add Video',
        type: PopoverItemType.AddVideo
      },
      {
        title: 'Batch Manage Videos',
        type: PopoverItemType.ManageVideo
      },
      {
        title: 'Modify Name',
        type: PopoverItemType.ModifyName
      },
      {
        // TODO: The copy should change dynamically based on the status
        title: 'Set as Public',
        type: PopoverItemType.ModifyPrivacy
      },
      {
        title: 'Delete Favorite',
        type: PopoverItemType.DeleteFolder
      }
    ]
  }

  build() {
    Column() {
      List() {
        ForEach(this.pub == '0' ? this.popoverItemList1 : this.popoverItemList2, (item: PopoverItem, index) => {
          ListItem() {
            Text(item.title)
          }
          .height(52)
          .padding({
            left: 16,
            right: 16,
            top: 14,
            bottom: 14
          })
          .onClick(() => {

          })
        }, (item: PopoverItem) => JSON.stringify(item.title))
      }
      .width('100%')
      .scrollBar(BarState.Off)
    }
    .width(161)
    .alignItems(HorizontalAlign.Center)
    .borderRadius(8)
  }
}

@Entry
@Component
export struct CollectionDetailPageNavBar {
  @State showPopover: boolean = false
  @State pub: boolean = true
  @Builder
  manageMenu() {
    CollectionManageMenu()
  }

  build() {
    Column() {
      Button('Manage')
        .width(62)
        .height(32)
        .borderRadius(16)
        .fontSize(15)
        .onClick(() => {
          this.showPopover = !this.showPopover
        })
        .bindPopup(
          this.showPopover,
          {
            builder: () => {
              this.manageMenu()
            },
            radius: 8,
            enableArrow: true,
            placement: Placement.BottomLeft,
            targetSpace: 20,
            offset: { x: -6 },
            onStateChange: (event) => {
              if (!event.isVisible) {
                this.showPopover = false
              }
            }
          }
        )

      Button('Change Private/Public Status')
        .width(62)
        .height(32)
        .borderRadius(16)
        .fontSize(15)
        .onClick(() => {
          this.pub = !this.pub
          AppStorage.SetOrCreate('pub', this.pub ? '0' : "1")
        })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

3. How to prevent a custom popup from closing when the back button is pressed in HarmonyOS?

An @Entry-decorated component can listen for back events by overriding onBackPress.

4. When loading pages via navigation in HarmonyOS, the first secondary page on a foldable screen in full-screen mode does not display the back button?

  • The primary page jumps to the secondary page via router.pushUrl.
  • The secondary page is written using Navigation, and navigating from the first secondary page to the second uses this.pageInfos.pushPathByName().

Solution:

Navigation uses hideBackButton to hide the back button in the title bar. This does not support hiding the back button in the NavDestination component's title bar.

  • Default: false (show back button)
  • true: Hide back button.
  • Note: The back button only takes effect when titleMode is NavigationTitleMode.Mini.

Reference document: https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/ts-basic-components-navigation-V5

5. How to achieve synchronous scaling of page layouts in HarmonyOS based on display size?

Use responsive layouts to dynamically adjust the page.

Reference: https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/responsive-layout-V5

Key points:

  • Adaptive layouts ensure normal display within a certain window size range, but significant size changes (e.g., from 400vp to 1000vp) may require responsive layouts to adjust page structure.
  • Responsive layouts allow elements to automatically adapt to external container changes based on specific features (e.g., window width, screen orientation).
  • The most common feature is window width, divided into breakpoints. When the width crosses a breakpoint, the layout adjusts (e.g., from single-column to multi-column) for optimal display.

Top comments (0)