EnsembleUI / ensemble

Build native apps 20x faster than Flutter, RN or any other tech
https://ensembleui.com/
BSD 3-Clause "New" or "Revised" License
118 stars 15 forks source link

`flutter: Looking up a deactivated widget's ancestor is unsafe.` #1471

Open TheNoumanDev opened 2 months ago

TheNoumanDev commented 2 months ago

So basically I have a base widget Radio whose layout is given in picture, where on button click i am opening a dialog RadioConfirmation and and its tree structure is also given, wot am trying to do is that it is not making 2 API calls but only first one is being maked set2gRadioAutoChannel and then it goes into the onResponse and also execute the code but then on calling API it gives the error show in picture as well.

flutter: Looking up a deactivated widget's ancestor is unsafe.
flutter: At this point the state of the widget's element tree is no longer stable.
flutter: To safely refer to a widget's ancestor in its dispose() method, save a reference to the ancestor by calling dependOnInheritedWidgetOfExactType() in the widget's didChangeDependencies() method.

image image image

TheNoumanDev commented 1 month ago

Hey @vusters @kmahmood74! After debugging I made an simple example EDL as given below, first i thought it has something to do with timer widget, but i tried it with loadingContainer and EDL explains it pretty clear that one's the Structure is broken by loadingWidget by deactivating the widget, it is not making actions or displaying any new widget. e.g on button's onTap it call the first API on the wont be calling the second API on its response. That should be the same case when we make one widget visible true and then false and then again true.

Example EDL (running it on studio will give null error and in emulator gives Looking up a deactivated widget's ancestor is unsafe. error):

View:
  styles:
    scrollableView: true
    showNavigation: false
  header:
    flexibleBackground: NetworkHealth
    styles:
      flexibleMaxHeight: 260
      flexibleMinHeight: 100
      backgroundColor: transparent
      surfaceTintColor: transparent

  onLoad:
    executeCode:
      body: |
        ensemble.storage.flag = true;
        console.log(ensemble.storage.flag);
      onComplete:
        executeActionGroup:
          actions:
            - invokeAPI:
                name: getPhotos
                onResponse: |
                  ensemble.storage.flag = false;
                  console.log(ensemble.storage.flag);
  body:
    Column:
      styles:
        borderRadius: 24 24 0 0
        padding: 32 16

NetworkHealth:
  body:
    Column:
      styles:
        backgroundColor: "${ ensemble.storage.flag ? 'black' : 'green' }"
      children:
        - Spacer:
            styles:
              size: ${ device.safeAreaTop + 8 }
        - LoadingContainer:
            isLoading: ${ ensemble.storage.flag }
            loadingWidget:
              Column:
                styles:
                  padding: 24
                  mainAxis: center
                  height: 200
                  gap: 16
                children:
                  - Progress:
                      styles:
                        size: 40
                        thickness: 4
                        color: white
                  - Text:
                      text: Checking Network
                      styles:
                        textStyle:
                          color: white
                          fontSize: 18
            widget:
              Column:
                styles:
                  padding: 0 16 8 24
                  gap: 24
                children:
                  - FlexRow:
                      styles:
                        mainAxis: spaceBetween
                        gap: 2
                      children:
                        - Text:
                            text: Network Looks good!
                            className: titleText1
                            styles:
                              padding: 32 0 0 0
                              flexMode: expanded
                              textStyle:
                                fontSize: 36
                  - Button:
                      label: verify
                      styles:
                        padding: 16 49
                        backgroundColor: white
                        labelStyle:
                          color: 0xff00aaff
                      onTap:
                        executeCode:
                          body: |
                            console.log("calling API");
                            ensemble.storage.flag = true;
                            console.log(ensemble.storage.flag);
                          onComplete:
                            # first API will be called but its onResponse will cause deactivated error.
                            invokeAPI:
                              name: getPhotos
                              onResponse:
                                invokeAPI:
                                  name: getPhotos
                                  onResponse: |
                                    ensemble.storage.flag = false;
                                    console.log(ensemble.storage.flag);
                            # but in the below way it will work unless onResponse is used😅
                            # executeActionGroup:
                            #   actions:
                            #     - invokeAPI:
                            #         name: getPhotos
                            #     - invokeAPI:
                            #         name: getPhotos

API:
  getPhotos:
    # Inputs for the API, including author for filtering
    inputs:
      - author
    url: https://picsum.photos/v2/list?page=2&limit=300
    method: GET