[Offline Apps] Caching Data from Structure instead of a Entity Object

[Offline Apps] Caching Data from Structure instead of a Entity Object

  
Forge Component
(25)
Published on 2015-11-19 by OutSystems Labs
25 votes
Published on 2015-11-19 by OutSystems Labs
Hi

I really like this Module. It can make my life alot easier. I have one slight problem. In my app that i am trying to implement , i am running into errors. I have isolated the problem to a advanced query/structure i am using instead of a simple query/Entity. The javascript gives the following error :

Uncaught TypeError: Cannot read property 'find' of undefined


When i change the output of the Advanced Query to a Entity all works fine , but when a structure is used i get this error.

Is this a shortcoming of the Offline module?

Regards

Arno
Hi Arno,

Right now it should be a shortcoming of the component, probabily on the HTML5OfflineUtils extension. Thank you for reporting it, it will be added to the backlog to be released in a future version.

If your needs are more urgent and you have some c# skills, you can try to change the extension serialization methods (that are roughly based on a previous version of the ardoJSON extension) to also support structures. If you do that please let me know as we can publish that new improved version here on the forge.

Thanks,
Tiago Simões

Hi Tiago

I have created a Entity Called EntityFieldAgentInbox to work around the Structure Problem.

The REST page returns the following :

[{"EntityFieldAgentInbox":{"JobId":"{EntityFieldAgentInbox.JobId}","TicketNumber":"{EntityFieldAgentInbox.TicketNumber}","OrderItemId":"{EntityFieldAgentInbox.OrderItemId}","TaskedDatetime":"{EntityFieldAgentInbox.TaskedDatetime}","DueDate":"{EntityFieldAgentInbox.DueDate}","Name":"{EntityFieldAgentInbox.Name}","TELEPHONE":"{EntityFieldAgentInbox.TELEPHONE}","BUILDING":"{EntityFieldAgentInbox.BUILDING}","STREETNAME":"{EntityFieldAgentInbox.STREETNAME}","city":"{EntityFieldAgentInbox.city}","TYPEOFSITE":"{EntityFieldAgentInbox.TYPEOFSITE}","JobType":"{EntityFieldAgentInbox.JobType}","DATETIMECREATED":"{EntityFieldAgentInbox.DATETIMECREATED}","JobStatus":"{EntityFieldAgentInbox.JobStatus}","FieldAgentAssignedTo":"{EntityFieldAgentInbox.FieldAgentAssignedTo}"}},{"EntityFieldAgentInbox":{"JobId":"","TicketNumber":"","OrderItemId":"","TaskedDatetime":"","DueDate":"","Name":"","TELEPHONE":"","BUILDING":"","STREETNAME":"","city":"","TYPEOFSITE":"","JobType":"","DATETIMECREATED":"","JobStatus":"","FieldAgentAssignedTo":""}},{"EntityFieldAgentInbox":{"JobId":"101","TicketNumber":"254851","OrderItemId":"119775","TaskedDatetime":"2014-07-14 15:00:37","DueDate":"","Name":"Tuinroete Agri Mossel Bay","TELEPHONE":"0446011200 / ","BUILDING":"","STREETNAME":"Industrial Road","city":"ossel Bay","TYPEOFSITE":"ProPOS Gold","JobType":"Installation","DATETIMECREATED":"2014-07-14 15:00:37","JobStatus":"Assigned","FieldAgentAssignedTo":"Not Assigned"}}]

The Java script on the on the List screen is calling the REST page but then i get the following error in the javascript : 

  1. Uncaught TypeError: Cannot read property 'find' of undefined OfflineStorageJavaScript.js?2406:219
    1. cachedList.replaceJQueryOfflineStorageJavaScript.js?2406:219
    2. cachedList.renderOfflineStorageJavaScript.js?2406:166
    3. (anonymous function)FieldAgentInbox.js?2581:15
    4. $.extend.each_osjs.js?8_0_1_7:18
    5. (anonymous function)FieldAgentInbox.js?2581:13
    6. loadListOfflineStorageJavaScript.js?2406:60
    7. (anonymous function)OfflineStorageJavaScript.js?2406:37
    8. l_osjs.js?8_0_1_7:18
    9. m.fireWith_osjs.js?8_0_1_7:18
    10. d_osjs.js?8_0_1_7:26
    11. d_osjs.js?8_0_1_7:26


       
I have worked through the tutorial plenty of times to see if i didnt miss anything , but everything looks OK.

Can you maybe guide in a direction to solve this problem.

Regards

Arno
Hi Arno,

What was the original code you used in the page?  
It's very hard to understand the problem just looking at that stack.

Cheers,
Tiago Simões
Hi Tiago

Here is the javascript that is supposed to populate the Table :
$(function() {
    
    var tableRecordsBody = $('.TableRecords tbody');
    
    //store and remove the template row
    var rowTemplate = tableRecordsBody.html();
    tableRecordsBody.empty();
    
    //Get the list from the server if online, or from the local storage if offline
    var records = new Offline.cachedList('REST_ENTITYFIELDAGENTINBOX.aspx', function() {
        var records = this;
        console.log(this);
        $.each(records, function() {
            //render a table row with the data
            var newRowHTML = records.render(rowTemplate, this);
            $(tableRecordsBody).append(newRowHTML);
        });
    });
    
    // search
    $('input[value=Search]').attr("onclick","").click(function(event) {
        var searchText = $('input[id$=SearchInput]').val().toUpperCase();
        tableRecordsBody.find('tr').each(function() {
            var rowHasText  = ($(this).text().toUpperCase().indexOf(searchText) >= 0);
            //show or hide the row depending if it contains the search text
            $(this).toggle(rowHasText);
        });
        event.preventDefault();
    });

    // reset
    $('input[value=Reset]').attr("onclick","").click(function(event) {
        $('input[id*=SearchInput]').val("");
        //show all rows
        tableRecordsBody.find('tr').show();
        //prevent the form from being submitted
        event.preventDefault();
    });    
    
});

Regards

Arno
Hi Arno,

That is very strange, rowTemplate should be a string and as such the cachedList.render() function should be redirecting to replaceText instead of replaceJQuery function. You can try to use chrome developer tools to put a breakpoint in the line:

            var newRowHTML = records.render(rowTemplate, this);

And make sure rowTemplate is in fact a string and then step into the render function to chek what's wrong.

Cheers,
Tiago Simões

PS: The "var tableRecordsBody = $('.TableRecords tbody');" selector assumes you only have one tablerecords on the screen and that it is using the default TableRecords style
 
Hi Tiago

Thanks for the help. It turns out that the table i was referring to had the incorrect style. I changed the style to TableRecords and it worked.

Many thanks again.

Arno

Hi Arno,

Welcome. It might be worth to test it again with a structure instead of the entity, as this might have been the original problem.

Cheers,
Tiago
Hi Tiago

I have tested with a structure with a working example. It works fine with a Entity , but gives errors with a structure.

Regards

Arno