JavaScript Stops Working After Pushing, Works Again When Resetting Navigator.



  • Hello,

    I can’t seem to find the source of this problem. The thing is, after I push a few pages to the navigator, the scripts that are responsible for adding dynamic DOM elements to pages suddenly stop working. They work again when I reset the navigator’s page stack.

    To start, here’s my main page:
    https://pastebin.com/bQrA9QuY
    As you can see, all scripts are included in the main page.

    Now, using the splitter’s side menu, I go to the “addPost.html” page.
    Here’s the splitter’s side HTML: https://pastebin.com/ZFqvFRtm
    And here’s the JavaScript file containing the fn.load function and other navigator functions: https://pastebin.com/L2JSAksP

    Now, after being in the addPost.html page, I click on a button which triggers the “addPost()” function in this script (https://pastebin.com/zLfxu3gK).

    On line 41, I load the “selectPostCategory.html” page alongside a function that fills an ons-list with ons-list-items loaded from a server (https://pastebin.com/AasP4m71).

    On line 70, I load the categories main page (https://pastebin.com/FESAZ6VN - Ignore the fn.with functions, they’re deprecated). Then I click on “Add Categories”, and the page is loaded. Inside the “Add Categories” page, the following function is called (https://pastebin.com/WnjzZfuw) which populates the ons-list with ons-list-items.

    Now, at some point, the rendering functions stop working. Here’s one case:
    1- Go to addPost.html. Clicking on a button calls the addPost() function and redirects us to “selectPostCategory.html” with which a function is called to populate an ons-list with items.
    2-Now being in “selectPostCategory.html” with a successfully populated list, we go to the “categories main page” and click choose “Add Category”.
    3-Now being in “Add Category”, we notice that the function responsible for populating the ons-list with items does nothing despite being called. I also tried calling it manually from the browser’s console. On the other hand, when I go to “Add Category” without doing step 1 and 2 (or by calling fn.reset()), the function responsible for rendering the categories in “Add Category” works perfectly.

    It seems this is the best I can explain this cumbersome problem, so thank you if you’ve made it this far.

    Peace.



  • I had a similar issue before. To solve it I used class names as opposed to ID’s in my javascript code.

    Note: i use jQuery so its a bit easier to use class names in jquery.

    But in Javascript, you can simply use:

    getElementsByClassName......
    

    I’m sure you know that anyway… : )



  • I have had a similar problem for many months. I have a navigator combined with a splitter, that utilizes the resetToPage() method. The first time I load a page with bootstrap-datepicker (npm), it loads fine. If I navigate to the same page, the datepicker does not load. If I navigate to a different page and then back again, it loads again.

    I have temporarily fixed this by adding a timeout to the script. So 500 milliseconds after the page loads, the datepicker script loads.

    Try adding a timeout? In JavaScript I think its

    setTimeout(function(){ alert("Hello"); }, 500);
    


  • @rgins16 Thanks for your reply. I think I don’t exactly have the same problem as you, since resetToPage() keeps working fine for me.

    @David-Hope I thank you wholeheartedly. This is it. Any idea why this happens though? I think it’s crucial to add it as a note in the documentation if this is how things are intended to be.


  • Onsen UI

    @4dnan I think there are some issues in your JavaScript code not directly related to Onsen UI. I tried to follow the flow until I found what I think is the first problem.

    fn.load('menu/posts/selectPostCategory.html', renderCategoriesListForSelection('', post_ID));
    

    I believe the second “argument” is wrong since you are actually calling renderCategoriesListForSelection function and sending its returned value to fn.load.

    Also, I think your fn.load is wrong:

    window.fn.load = function(page, then, options) {
      ...
      content.pushPage(page, options)
        .then(function(){ menu.close.bind(menu); then;});
    };
    

    Here, in function(){ menu.close.bind(menu); then;} you are just evaluating then argument but not calling it (it is supposed to be a function). Even the menu.close.bind(menu) part shouldn’t be working.

    I think what you want to do in the first place is fn.load('menu/posts/selectPostCategory.html', renderCategoriesListForSelection.bind(null, '', post_ID)); and after that .then(function(){ menu.close(); then();}); (notice the parentheses).
    You can also simply return the promise you have in fn.load and handle it in addPost: fn.load('...').then(function() { renderWhatever(); }.

    Basically, I think you are somehow rendering stuff before pushing the other page. I don’t know why classes work and IDs don’t, but I’m quite sure it is related to flow and timing issues in the app. Not sure if there are other issues.

    I’d recommend you having a look at page lifecycle events and use it to initialize page data.



  • @4dnan No problem.

    I have no idea why to be honest but I spent hours and finally figured that out.

    I suspect its because the DOM doesn’t get removed completely when you change pages! Because when I inspect the elements in the console, I see the old DOM elements in there (greyed out)!

    which means the same ID is in the page a multiple times thus javascript/jquery cannot select the element(s) with an ID so the Class names works.

    There is another thing that I could suggest is to use

    document.addEventListener("init", function(event){
    
    
    if(event.target.id ==='home') {
    
    ///YOUR CODE HERE////
    
    }
    
    });
    

    and if that doesn’t work, you can use

    
    document.addEventListener("show", function(event){
    
    
    if(event.target.id ==='home') {
    
    ///Your code here///
    
    }
    
    });
    

    As @Fran-Diox rightly said it, its all about the timing issue.



  • Thanks for your replies. @Fran-Diox, I had also tried calling the method in the postPush event before doing the then function.

    Now I noticed this problem again with form inputs. Here’s an example:
    document.getElementsByClassName('postText').length // returns 1 when the page is first loaded
    document.getElementsByClassName('postText').length // returns 2 when the page is loaded again.

    For the time being I can simply select the last element by class name, but I’m afraid of performance drawbacks. Plus, the “clever hacks” in the code are too much.

    Would using the events solve this problem ?


Log in to reply