Framework7 : Load Ajax Content when router-tabs open

I try to understand somethings on framework7 to built an hybrid app. I have an app with router tabs like this :

{
path: '/pro/',
url: './pages_pro/index.html',
tabs: [
  {
// Tab path
path: '/',
// Tab id
id: 'tab-1',
url: './pages_pro/A.html',
  },
  // Second tab
  {
path: '/tab-2/',
id: 'tab-2',
url: './pages_pro/B.html',
  },
  // Third tab
  {
path: '/tab-3/',
id: 'tab-3',
 url: './pages_pro/C.html',
  },
   ],

},

I would like to load content from API using ajax and php when a tab is open.

An idea to helping me ?

Thank you !

Use async routing… This kind of routing helps you when you want Javascript to puase and wait for you to do somehting like make an API request and get data before continuing…

Read through the guide to understand it…

sample

  {
  path: '/some-path/:param',
  async: function (routeTo, routeFrom, resolve, reject) {
     
      var router = this;
      var app = router.app;

      var param = routeTo.params.param;

      app.dialog.preloader();; //Preloader

      app.request({
          url: API_ENDPOINT,
          dataType: 'json',
          method: 'GET',
          cache: false,
          crossDomain: true,
          success: function (data) {
             app.dialog.close(); //close preloader

              resolve(
                  {
                    componentUrl: './pages/some-page.html'
                  }, 
                  {
                    context: {
                      info: data,
                    }
                  }
            );
          }
        },
        error: function () {
         app.dialog.close();

            app.dialog.alert('Failed To Make Request!');
            reject();
        }
      });
    }
  },

I already try but it doesn’t works :frowning_face:
Nothing append in my console (no call to the api url).

 {
 path: '/pro/',
 url: './pages_pro/index.html',
   tabs: [
   {
     path: '/',
     id: 'tab-1',

     async: function (routeTo, routeFrom, resolve, reject) {
        // Router instance
        var router = this;
        // App instance
       var app = router.app;
       var idcat="1";

      // Show Preloader
      app.preloader.show();

      app.request({
        url: 'http://api.casanova-life.com/pro/souscategorie.php',
        type: "GET",
        dataType: 'json',
        data: "idcat="+idcat,
        timeout: 1000,
        success: function(reponse){
                if(reponse['success']==true && reponse['results']['nb']>0)
                {   

                    var sub_cat=[];

                    for(var key in reponse['results']) 
                    {
                      if(!sub_cat[key])
                      {
                          sub_cat[key] = [];
                      }
                        sub_cat[key]['idcat']=reponse['results'][key].idcat;
                        sub_cat[key]['idsubcat']=reponse['results'][key].idsubcat;
                        sub_cat[key]['titre']=reponse['results'][key].titre;
                        sub_cat[key]['url']="/sub_cat/"+sub_cat[key]['idcat']+"/"+sub_cat[key]['idsubcat']+"/";
                    }
                }
                else if(reponse['error']=="noresult")
                {

                }
                app.preloader.hide();
                // Resolve route to load page
                resolve(
                  {
                    componentUrl: './pages_pro/test.html',

                  },
                  {
                    context: {
                      sub_cat: sub_cat,
                    }

                  }

                );
        },
        error: function(){
              if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) 
              {
                 app.preloader.hide();
                  navigator.notification.confirm(
                     "Error during loading data\n Try again ?",
                        callback_refresh_result,
                        'Information',
                        'No,Yes');
              }
              else
              {
                app.preloader.hide();
                  alert("Error during loading data");
              }

        }
      })
    }, // FIN ASYNC 
   },

My test.html file

    <template>
    <div class="page" data-page="test">
      <div class="page-content">
        <div class="block-title">TEST</div>
        <div class="list">
        <ul>
          {{#each sub_cat}}
            <li><a href="{{url}}" class="item-content item-link" data-idcat="{{idcat}}" data-idtitre=" {{idsubcat}}"><div class="item-inner"><div class="item-title">{{title}}</div></div></a></li>
          {{/each}}
        </ul>
      </div>
       
      </div>
      <!-- End of PAGE CONTENT-->
    </div>
    <!-- End of PAGE RESIDENTIEL-->
    </template>
  <script>
    return {}
  </script>

Do you have an idea to help me ?

Thank you !!! :slight_smile:

For starters, you have a CORS problem… Your API call is never successful…

2, from your API response, I just think yo are complicating things…

keep things simple…

Like…

               {
                componentUrl: './pages_pro/test.html',
              },
              {
                context: {
                  sub_cat: response.results,
                }

then on your component, use something like this:

{{#each sub_cat}}
  ..... <!--Access elements of sub_cat-->
{{else}}
...<!--Nothing, empty array-->
{{/each}}

Like where do you get idsubcat from in :sub_cat[key]['url']="/sub_cat/"+sub_cat[key]['idcat']+"/"+sub_cat[key]['idsubcat']+"/";

because your API response in postman is different as seen below (part of it):

Capture

Read through this Template7 document too, very imprtant

if idsouscat in your response is idsubcat above in your request code, the on your template it is easy to construct your URL there too easily i your {{#each}}...{{else}}...{{/each}}

Like below,

<a href="/sub_cat/{{idcat}}/{{idsubcat}}/">URL<a/>

Thank you Max.
The thing is when I putt my async code before tabs[{}] the app make a call to my api and it’s works.
When I putt async code in tabs router I have no call to api on the console.

Do you think is impossible to make async call in tabs ?

Routable tabs should accept all forms of routes, async is just something, ‘hey, before you conclude on where to direct the user, please, let me do something first, will tell you when am ready’… This way, all routing is paused, and the app waits for you to do anything, until you resolve() or reject ()… So It really should work… Let me ready myself and test with my own code…

1 Like

Hello… I realised it’s actually possible, But I proved, async routes are very possible…with routable tabs…

Try to understand this explanation
You can fill a component in a separate file with contents of your tab…

Tabs can be async. Just tried to modify Kitchen Sink routable tab to the following:

{
  path: '/tabs-routable/',
  url: './pages/tabs-routable.html',
  tabs: [
    {
      path: '/',
      id: 'tab1',
      async(to, from, resolve, reject) {
        setTimeout(() => {
          resolve({
            componentUrl: './something.html',
          }, {
            context: {foo: 'bar'},
          });
        }, 3000);
      },
    },
    ...
  ],
}

something.html

<template>
  <div class="block">Hello {{foo}}</div>
</template>

All works as expected

1 Like

So check for issue on your side, there is something there

Thank you Nolimits4web and Max !
With your help and framework version upgrading (2 to 3) it works now.

:hugs: :hugs: :hugs:

Just a last question : is there possible to charge tabs content via async one time ?
Ex : on the opening, the app charge all the async tabs content and when the user navigate no content is refreshed ?