0
votes

I think I'm missing a core concept in how to filter and display App Maker data.

Goal

1) I'd like to maintain two manual-mode data models.

Persons:
  PrimaryEmail
  personName
Vehicles:
  PrimaryEmail
  vehicleColor

2) I'd like to display two tables side by side on the same page.

Showing all the vehicles in one table and only the user's vehicles in the second table. PrimaryEmail is the key they share.


What I've Tried

Server Script

This query script for a third datasource, UserVehicles, returns the records I want to display in the second table.

function getUserVehicleData() {
  var uE = Session.getActiveUser().getEmail();
  var q = app.models.Vehicle.newQuery();
  q.filters.PrimaryEmail._equals = uE;
  var d = q.run();
  return d;
}

But, I found it necessary for the client to frequently call app.datasources.UserVehicle.load(); but even still the second table would not show the updated/added record from (table one uses the Vehicle datasource, table two is using UserVehicles). I think I need to also work inside the load() callback, but I do not see how to tell the second table there is refreshed data in UserVehicles.

Client Calculated

This option sounds right. I'd like the client to query the server for the records where the Vehicle's PrimaryEmail matches the current user.

I do not see how records from the server are filtered on the client. Unlike the server script API, var data = app.models.Vehicle.newQuery(); is not valid client script. So, one does not load data into variables in which to loop/filter/create new records in the client calculated script?

Relations

I replicated a tutorial and created a ONE to MANY relations between People and Vehicles. This introduced errors around deprecated foreign keys. Also, I couldn't reason how to use this relation to the filter for the current user. (I'm not 100% grasping the UI).

Question

I want to understand how to display updated and filtered data and how that data should be filtered (server, client calculated, relations). I must be missing something, this must be simple to do.

1
Many ways to approach this, but the easiest is have your persons table, if you wish to filter this then apply the filter in the datasource's query script with a query of query.filters.PrimaryEmail._equals() = Session.getActiveUser().getEmail() then in your panel where you have the persons table make sure the panel datasource is set to 'persons' and drag a new table into this panel with datasource as persons: vehicles (relation). Also make sure to prefetch vehicles in your persons datasource. - Markus Malessa
Where does query.filters.PrimaryEmail._equals() = Session.getActiveUser().getEmail() go? The datasource query script must return an array of records. Prefetch is a big help, Thanks! - Chadd
That filter goes in your datasource query script (server) for persons, but only if you need persons filtered based on the current user. If you need all/several persons returned then don’t apply the filter. - Markus Malessa
Call one 'AllVehicles' and the other 'UserVehicles' or whatever suits your needs. Have both datasources set to automatically load. On the AllVehicles datasource leave the query builder active and don't enter anything. - Markus Malessa
On the UserVehicles datasource change it to query script and enter query.filters.PrimaryEmail._equals() = Session.getActiveUser().getEmail(); in the case that there is no relation between persons and vehicles, or query.filters.Persons.PrimaryEmail._equals() = Session.getActiveUser().getEmail(); in the case that there is a relation between persons and vehicles. Then add return query.run(); on the second line of your query script. - Markus Malessa

1 Answers

0
votes

Solved

I used a server script to solve this.

function getUserVehicleData() {
  var uE = Session.getActiveUser().getEmail();
  var q = app.models.Vehicle.newQuery();
  q.filters.PrimaryEmail._equals = uE;
  var d = q.run();
  return d;
}

The piece I was missing was this bit of Client Script.

app.pages.UserVehicles.createChildren();

Without it, the UI would not refresh the list to use the updated data from the datasource.

Thanks Markus!