Power Apps Offline Mode: A Step-By-Step Tutorial

Power Apps Offline Mode: A Step-By-Step Tutorial



Mobile Power Apps for tablets or phones still have to work when there is no internet connection. As a developer, making Power Apps with an offline mode is one of the the greatest challenges you will undertake. It requires careful planning to ensure no data is lost when the device goes offline and to quickly upload a large amount of data when the device comes back online.

In this article I will show you a full example of how to build mobile Power Apps with an offline mode.




Introduction: Home Inspection App

The Home Inspection App is a tablet app used by employees of a company that performs home inspections for new home buyers. After an employee looks-over the home they submit a report on its condition via the app. Sometimes the employee is not in range of a cellular signal or wifi so an offline mode must be included in the app. When the app is offline any reports will be saved to the tablet. Then when the tablet comes in range of internet service once again the reports will be saved back to the datasource.




The Setup

Create a SharePoint list called Home Inspections with the following columns:

  • Address (single line of text)
  • StartTime (date and time)
  • Assigned To (person)

Load the following data into the SharePoint list. Change the AssignedTo column to match your own name.

AddressStartTimeAssignedToReport
30 State Street1/9/2020 9:00AMMatthew Devaney
200 Broadway Ave1/9/2020 11:00AMMatthew Devaney
15 Circle Road1/9/2020 1:30PMMatthew Devaney



Open Power Apps and start a new canvas app from blank. Connect the app to the Home Inspections SharePoint list. Then write this code in the OnStart property of the app.

// get the current user's email
Set(
     varUserEmail,
     User().Email
 );
// load home inspections data into collection
 ClearCollect(
     colHomeInspections,
     Filter(
         'Home Inspections',
         AssignedTo.Email=varUserEmail
     )
 );



Insert a new screen called Gallery Screen. On this screen the employee selects a home inspection appointment from a list and goes to the next screen to write a report.

Place a gallery on the screen with Home Inspections as the Items property.



Then write this code in the OnSelect property of the the gallery. You will get some errors because we have not created the Form Screen or the Edit Form. We will do that next and the errors should go away.

Set(varCurrentRecord, ThisItem);
EditForm(frm_Form_Main);
Navigate('Form Screen');



Next, insert another screen called Form Screen. Add an Edit Form to the screen called frm_Form_Main and use Home Inspections as the datasource.



Place the varCurrentRecord variable in the Item property of the form. Now when the employee selects a home inspection appointment from the list it will appear in the form.

varCurrentRecord


The employee needs a way to go back to the Gallery screen if they have chosen the wrong appointment. Make a Left Arrow icon and put this code in the OnSelect property.

Navigate('Gallery Screen')



There are 3 more blank screens we should create right now. However, we will not write any code for them until later.

  • Saving Screen
  • Loading Screen
  • Admin Screen




Editing Records In Power Apps Offline Mode

The employee opens the appointment, writes a report and submits it to SharePoint once complete. When the tablet does not have internet service the changed appointment record must be saved to the local device instead.

Place a Submit button on the screen directly below the Edit Form.



Write this code in the OnSelect property of the Submit button. It will save the form data to the colHomeInspections collection and then save colHomeInspections to the local device. Notice that we are not trying to update the SharePoint list yet. We will check for a connection and try to do that on the Saving Screen .

// update collection with form data
 Patch(
     colHomeInspections,
     LookUp(colHomeInspections, ID=varCurrentRecord.ID),
     frm_Form_Main.Updates
 );
 // save collection to local device
 SaveData(
     colHomeInspections,
     "localHomeInspections"
 );



Additionally, we need to track which record was edited in a new collection called colUnsavedRecords. We will also save colUnsavedRecords to the local device in case there is no internet connection. Then the app will go to the saving screen.

Add this code to the OnSelect property of the Submit button as well.

// update collection with form data
 Patch(
     colHomeInspections,
     LookUp(colHomeInspections, ID=varCurrentRecord.ID),
     frm_Form_Main.Updates
 );
 // save collection to local device
 SaveData(
     colHomeInspections,
     "localHomeInspections"
 );

/* more code added below */

 // track record that was edited
 Collect(
     colUnsavedRecords,
     {ID: varCurrentRecord.ID}
 );
 // save collection to local device
 SaveData(
     colUnsavedRecords,
     "localUnsavedRecords"
 );
 Navigate('Saving Screen');




Admin Screen

When the app is in Play mode we want the Loading Screen and Saving Screen to run automatically. But when the app is in Studio mode we need a way to disable the loading and saving from happening so we can work on that functionality. We can do this by enabling ‘Debug Mode’ on the Admin Screen. Debug mode is not something built into Power Apps, it is something we are building for ourselves.

Go to the Admin Screen and insert a new toggle called tog_DebugMode.



Then set the Default property of the toggle to false.

false



Click on the toggle and set it to true to disable automatic loading and saving on the next screens.




Saving Screen

Now its time to save the edited record back to the Home Inspections SharePoint list. Open the Saving Screen and place two new controls on the canvas:

  • A label called lbl_Saving_Message to display the saving status
  • A button called btn_Saving_Actions to hold the saving code




Use this code in the OnVisible property of the screen. It will click the button btn_Saving_Actions when the Saving Screen is opened unless the app is in Debug Mode.

If(!tog_DebugMode.Value, Select(btn_Saving_Actions))



Put this code in the OnSelect property of the button to check if the device is connected to the internet and write the unsaved records back to SharePoint.

// Check if device is online
If(Connection.Connected,

    // Add or update records in SharePoint
    Patch(
        'Home Inspections',
        // Choose which columns are written to SharePoint 
        ShowColumns(
            // Only write records with ID found in colUnsavedRecords
            Filter(
                colHomeInspections,
                ID in colUnsavedRecords.ID
            ),
            "ID",
            "Address",
            "StartTime",
            "AssignedTo",
            "Report"
        )
    );

    // Clear unsaved records collection
    Clear(colUnsavedRecords);
    SaveData(
        colUnsavedRecords,
        "localUnsavedRecords"
    );
);

UpdateContext({locMessage: "Saving completed"});
Navigate('Loading Screen');



To let the user know what is currently happening during the save process use the locMessage variable in the Text property of the label lbl_Saving_Message.

locMessage




Loading Screen

The Loading Screen is structured similarly to the Saving Screen. Open the Loading Screen and place two new controls on the canvas:

  • A label called lbl_Loading_Message to display the loading status
  • A button called btn_Loading_Actions to hold the loading code




Use this code in the OnVisible property of the screen.

If(!tog_DebugMode.Value, Select(btn_Loading_Actions))



Put this code in the OnSelect property of the button to check if the device is connected to the internet and either load the data from SharePoint or obtain it from the local device.

UpdateContext({locMessage: "Checking your connection..."});
LoadData(colUnsavedRecords, "localUnsavedRecords", true);

// Check if device is online
If(
    Connection.Connected And IsEmpty(colUnsavedRecords),

    //  Get data from SharePoint
    UpdateContext({locMessage: "Loading your data from SharePoint..."});
    ClearCollect(
        colHomeInspections,
        // Only data for the current user
        Filter(
            'Home Inspections',
            AssignedTo.Email=varUserEmail
        )
    );
    SaveData(colHomeInspections, "localHomeInspections"),

    // Get data from local device
    UpdateContext({locMessage: "Loading your data from Local Device..."});
    Clear(colHomeInspections);
    LoadData(colHomeInspections, "localHomeInspections", true);
);

UpdateContext({locMessage: "Loading completed"});
Navigate('Gallery Screen');


Write the locMessage variable in the Text property of the label lbl_Loading_Message.

locMessage



Finally, go back to the OnStart property of the app, remove any code and replace it with this.

Set(varUserEmail, User().Email);



The Home Inspections App can now edit records in Power Apps offline mode.




Adding Records In Power Apps Offline Mode

An employee should be able to add a new home inspection appointment to the app. Including this functionality is very simple. We can accomplish it by adding some extra code in two sections.

Insert a new Add icon onto the Gallery Screen



…and copy this code into the OnSelect property.


Set(varCurrentRecord, Blank());
NewForm(frm_Form_Main);
Navigate('Form Screen');



Then go to the Form Screen



…and update the OnSelect property of the submit button with this code.

// update collection with form data
 Patch(
     colHomeInspections,
     /* updated code here */
     Coalesce(
         LookUp(colHomeInspections,
             ID=varCurrentRecord.ID),
             Defaults(colHomeInspections)
     ),
     frm_Form_Main.Updates
 );
 // save collection to local device
 SaveData(
     colHomeInspections,
     "localHomeInspections"
 );
 // track record that was edited
 Collect(
     colUnsavedRecords,
     {ID: varCurrentRecord.ID}
 );
 // save collection to local device
 SaveData(
     colUnsavedRecords,
     "localUnsavedRecords"
 );
 Navigate('Saving Screen');



Those small changes are all it takes to add new records with Power Apps offline mode.




Deleting Records In Power Apps Offline Mode

Removing home inspection appointments is a bit more involved. We must get rid of the record on the local device and track anything that was removed until a sync with SharePoint can be performed.


Open the Form Screen and add a Trash icon to the top right corner.



Write this code in the OnSelect property of the Trash icon. It will delete the record from the colHomeInspections collection and save colHomeInspections to the local device.

// update collection with form data
 Remove(
     colHomeInspections,
     LookUp(colHomeInspections, ID=varCurrentRecord.ID)
 );
 // save collection to local device
 SaveData(
     colHomeInspections,
     "localHomeInspections"
 );



Also, we need to track which record was deleted in a new collection called colDeletedRecords. We will also save colDeletedRecords to the local device in case there is no internet connection. Then the app will go to the saving screen.

// update collection with form data
 Remove(
     colHomeInspections,
     LookUp(colHomeInspections, ID=varCurrentRecord.ID)
 );
 // save collection to local device
 SaveData(
     colHomeInspections,
     "localHomeInspections"
 );

 /* more code added below */

 // track record that was edited
 Collect(
     colDeletedRecords,
     {ID: varCurrentRecord.ID}
 );
 // save collection to local device
 SaveData(
     colDeletedRecords,
     "localDeletedRecords"
 );
 Navigate('Saving Screen')



Go to the Saving Screen



…and add this code to delete the records from SharePoint when the device is connected.

UpdateContext({locMessage: "Saving your data..."});

// Check if device is online
If(Connection.Connected,

    // Add or update records in SharePoint
    Patch(
        'Home Inspections',
        ShowColumns(
            Filter(
                colHomeInspections,
                ID in colUnsavedRecords.ID
            ),
            "ID",
            "Address",
            "StartTime",
            "AssignedTo",
            "Report"
        )
    );

    // Clear unsaved records collection
    Clear(colUnsavedRecords);
    SaveData(
        colUnsavedRecords,
        "localUnsavedRecords"
    );

    /* added code here */

    // Delete records from SharePoint
    ForAll(
        colDeletedRecords,
        Remove(
            'Home Inspections',
            LookUp(
                'Home Inspections',
                ID=colDeletedRecords[@ID]
            )
        )
    );
    
    // Clear deleted records collection
    Clear(colDeletedRecords);
    SaveData(
        colDeletedRecords,
        "localDeletedRecords"
    );
);

UpdateContext({locMessage: "Saving completed"});
Navigate('Loading Screen');



Then go to the Loading Screen



…and add this code to load colDeletedRecords from the local device if the device unexpectedly went offline and prevent the app from loading the deleted record from SharePoint.

UpdateContext({locMessage: "Checking your connection..."});
LoadData(colUnsavedRecords, "localUnsavedRecords", true);
/* added code here */
LoadData(colDeletedRecords, "localDeletedRecords", true);

// Check if device is online
If(
    /* updated code here */
    Connection.Connected
    And IsEmpty(colUnsavedRecords)
    And IsEmpty(colDeletedRecords),

    //  Get data from SharePoint
    UpdateContext({locMessage: "Loading your data from SharePoint..."});
    ClearCollect(
        colHomeInspections,
        Filter(
            'Home Inspections',
            AssignedTo.Email=varUserEmail
        )
    );
    SaveData(colHomeInspections, "localHomeInspections"),

    // Get data from local device
    UpdateContext({locMessage: "Loading your data from Local Device..."});
    Clear(colHomeInspections);
    LoadData(colHomeInspections, "localHomeInspections", true);
);

UpdateContext({locMessage: "Loading completed"});
Navigate('Gallery Screen');



Now the app can successfully delete records using Power Apps offline mode.




Refresh Button

The last feature we will add is a refresh button so the employee can sync the local device’s data to the SharePoint list on-demand. Create a Refresh icon and place it in the top-left corner of the Gallery Screen.



Use this code in the OnSelect property of the Refresh icon to navigate to the saving screen. The app will save any unsaved records to the SharePoint list then load any updated records form the SharePoint list.

Navigate('Saving Screen')


We have now fully implemented Power Apps offline mode for the Home Inspections app.





Questions?

If you have any questions or feedback about Power Apps Offline Mode please leave a message in the comments section below. You can post using your email address and are not required to create an account to join the discussion.

Matthew Devaney

Subscribe
Notify of
guest
26 Comments
Oldest
Newest
Inline Feedbacks
View all comments
Connor
Connor
1 year ago

This is the best guide and approach for creating offline apps; thank you very much!

Last edited 1 year ago by Connor
Carl Williams
1 year ago

Thanks Matthew. I’ve been doing PowerApps for some time and have an extensive grocery/shopping app I created over the past little while. However, it’s quite data intensive (seemingly) and runs on wi-fi or cell connection so a little ratchety.

I’ve been wanting to implement this kind of collections technique but everyone has a little text box updating a small connection. Very basic.

This is exactly what I’ve been looking for!!!

BTW, if you would like a copy of my app I’d be happy to share it with you in case you want to use as another collections idea/technique. Just email me if you’re interested. But dont laugh.:)

Carl

Carl Williams
1 year ago

Hey Matthew. For those that may not realize, the comment line for the OnSelect property of the btn_Savings_Actions on the Saving Screen:

 \\ Only write records with ID found in colUnsavedRecords

will produce a syntax error. You probable meant forward slashes:

 // Only write records with ID found in colUnsavedRecords
Carl Williams
1 year ago

Just finished creating this app after realizing the debug mode was giving me all the errors in the code. Duh, I guess that’s why it’s called Debug mode although I haven’t tested it offline yet though.

I had no idea it was this involved to create an online-offline mode app. I was going to do this with my Grocery App but hmmm that’ll take some time to implement given all the connections and fields I have to deal with.

If I get it working I’ll probably receive a degree in computer engineering thanks to your example!!

Anyway, Great job and thanks again for sharing with us!!

Bill Kuhn
Bill Kuhn
11 months ago

If you have a dropdown that gets its values (the values the user sees when he clicks the dropdown chevron) from a SharePoint list (items property set as shown below) and you are offline, how does the dropdown get the values from the SharePoint list?

Items = Choices(MySPList.MySPChoiceColumn)

Sorry if I missed this in your post above.

Kind regards,
Bill

Bill Kuhn
Bill Kuhn
11 months ago

So if I’m understanding correctly, the user has to be online at some point to build the collection of dropdown choices used in the app. In other words, if I build an app and publish it and then “Joe User” opens the app for the first time ever on his device and he happens to be offline, he will not be able to build the collection that supplies the apps dropdowns with choice values. Is that correct?

One other question comes to mind…I’m assuming that certain controls, like a combo box set to my company’s directory (using the Office365Users connector) will not work as I cannot easily load 100K users into a collection for offline use?

Matthew Devaney
Matthew Devaney
11 months ago
Reply to  Bill Kuhn

Yes, the user does have to be online at least once. If you want to make an app where the user will never be online that’s a different story altogether.

As for the 100k users question, that’s a scenario where offline simply won’t work. But I doubt that most times you’d need all 100k users to be visible to the app. Most likely just a department or division in a company. The standard workaround is to create a whitelist of app users.

Howard Nathan
Howard Nathan
9 months ago

Matthew-

Thanks so much for this post! I have more than several hours in trying to get my offline app working properly. Your explanation was spot on!

The list I’m working with has 30 some odd choice fields. I have the collection working properly and I believe the data is saved to my phone correctly. Just trying to figure out how to bring them back to the individual drop-downs when offline.

You end your reply with replacing the items code with colChoicesOptions.ChoicesName1. I’m assuming I’ll have 30 lines similar to that one, just not sure where to put them. Do they somehow go in the LoadData function? Not sure on the syntax here but, it’s late!

Any guidance would be greatly appreciated!

Thanks again!
Howard

Himani
Himani
9 months ago

Hi Mathew,
Thanks much for this blog. It really is helpful. I have a requirement wherein I want photos to be added in the offline mode alongside these details.Could you please help with that.

Thanks

Brad
Brad
1 month ago

My first question is if one is offline then I would assume this first step would not happen:

// load home inspections data into collection
ClearCollect(
colHomeInspections,
Filter(
‘Home Inspections’,
AssignedTo.Email=varUserEmail
)
);

If a user goes into the app initially and is offline then editing would not be possible, correct?

Colby Turybury
Colby Turybury
21 days ago

Slow Clap!!!! Thankyou so much for this article! The app has really opened my mind to what is possible.

My only question is how do you handle the “Title” column in Sharepoint? I basically assign a GUID() and hide the title datacard. You don’t address that.

Paul
Paul
21 days ago

Hello

I have followed this using the current version of Sharepoint.

There is now a Title column mandatory in lists

I show that on the forms and set it when I add a new record, but I get the error that title must be specified

Any ideas?

Paul

Paul
Paul
21 days ago

I tried that and I still get the same issue?

Paul
Paul
20 days ago

Has anyone ever had the message an unknown error has occurred when testing this with no internet?

I get this when I submit a change when there is no connection to the internet

Paul
Paul
20 days ago

Hello

My users want to be able to add attachments

This could be anything such as documents or photos

How can I do this? I wonโ€™t have to worry about conflicts as there will only be one person editing an entry at a time

I.e I wonโ€™t get a situation where an entry is updated in Sharepoint after itโ€™s been downloaded to a device but before the device version is uploaded

I have to use Sharepoint

The post below talks about photos but my requirement is a bit more generic

Is there a way of getting date last updated?

Paul

Jonas
Jonas
5 days ago
Reply to  Paul

You may use the Base64 representation of the image, save it to a multiline field. When you are connected, you can upload with a Power Automate Flow

Paul
Paul
18 days ago

Hello

When I turn Airplane mode on on my device I keep getting errors

For example, when no internet connection exists I go to edit an entry and although it should be reading from the offline list I get an error “The request was not sent or there was no response from the server

Has anyone else had this?

Likewise, when I add a new record and submit it in Airplay mode I get the the same error

Any ideas?

Paul

Paul
Paul
16 days ago

Hi Matthew

My app’s requirement is to bring up a gallery with a search box and have that fill the local collection. How can I do that?

Paul