Reports submitted by an offline user do not sync up to CouchDB

I have a form that works fine, but when I attempt to access an attribute from the resulting JSON document, I get the error TypeError: Cannot read property 'fields' of null

I am using the Utils.getField(report, 'visit_verification.missed_appointment') function, see examples on this page and my resulting JSON is as follows:

{
  form: 'visit_verification',
  type: 'data_record',
  content_type: 'xml',
  reported_date: 1656237028034,
  fields: {
    inputs: {
      meta: [Object],
      source: 'task',
      source_id: 'e95ef8ab-8adb-4e82-a215-d2bfa1846dbd',
      t_patient_id: 'patient_id',
      t_patient_name: 'Patient Name',
      t_patient_sex: '',
      t_chw_name: '',
      t_chw_phone: '',
      t_patient_age_in_years: '4',
      t_patient_age_in_months: '59',
      t_patient_age_in_days: '',
      t_patient_age_display: '',
      t_supervisor_phone: '+17782473214',
      t_medic_patient_id: 'patient_id',
      t_missed_appointment_date: '',
      t_trace_reasons: '',
      t_emr_id: '',
      contact: [Object]
    },
    source: 'task',
    source_id: 'e95ef8ab-8adb-4e82-a215-d2bfa1846dbd',
    patient_uuid: 'patient_id',
    dob: '2017-07-09',
    geolocation: '',
    patient_age_in_years: '4',
    patient_age_in_months: '59',
    patient_age_in_days: '1813',
    patient_age_display: '4 years and 11 months old',
    patient_id: 'patient_id',
    patient_name: 'Patient Name',
    patient_name_display: 'Patient Name',
    patient_sex: 'female',
    chw_name: '',
    chw_phone: '',
    missed_appointment_date: '',
    trace_reasons: '',
    emr_id: '',
    needs_signoff: 'true',
    supervisor_phone: '+17782473214',
    visit_verification: {
      n_patient_name: '',
      n_patient_emr_id: '',
      n_trace_reason: '',
      n_missed_appointment_date: '',
      missed_appointment: 'yes'
    },
    meta: { instanceID: 'uuid:de25e446-20c3-4445-baaf-d7fcb43152ce' },
    trace_report_date: '2022-06-24'
  },
  _id: '5d68e0a5-8453-4787-87ff-7bdc3e16d9e5',
  _rev: '1-949aa69921f0fcb1a716cd666e8bbbec'
}

What could I be possibly missing?

Can you please share your config that throws this error?
TypeError: Cannot read property 'fields' of null indicates that your report variable is null.

This.

{
    name: 'trace-follow-up',
    icon: 'icon-followup-general',
    title: 'task.title.trace_follow_up',
    appliesTo: 'reports',
    appliesToType: ['trace'],
    appliesIf: function (c, r) {
      const report = getNewestReport(c.reports, ['visit_verification']);
      return getField(r, 'trace_report_date') === getField(report, 'trace_report_date') &&
        getField(report, 'visit_verification.missed_appointment') === 'yes' &&
        isAlive(c.contact) &&
        !isMuted(c.contact);
    },
    actions: [
      {
        type: 'report',
        form: 'trace_follow_up',
        modifyContent: function (content, c, report) {
          content.t_patient_name = c.contact.name;
          content.t_patient_id = c.contact.uuid;
          content.t_emr_uuid = c.contact.emr_uuid;
          content.t_medic_patient_id = c.contact.patient_id;
          content.t_chw_name = getField(report, 'chw_name');
          content.t_chw_phone = getField(report, 'chw_phone');
          content.t_patient_age_in_years = getField(report, 'patient_age_in_years');
          content.t_patient_age_in_months = getField(report, 'patient_age_in_months');
          content.t_patient_age_in_days = getField(report, 'patient_age_in_days');
          content.t_patient_sex = c.contact.sex;
          content.t_missed_appointment_date = getField(report, 'missed_appointment_date');
          content.t_trace_reasons = getField(report, 'trace_reasons');
          content.t_emr_id = getField(report, 'emr_id');
          content.t_emr_trace_report_date = getField(report, 'trace_report_date');
        }
      }
    ],
    events: [
      {
        id: 'trace-follow-up',
        days: 3,
        start: 1,
        end: 8
      }
    ],
    resolvedIf: function (c, r, event, dueDate) {
      const newestTrace = getNewestReport(c.reports, ['trace']);
      return isFormArraySubmittedInWindow(c.reports, ['trace_follow_up'], dueDate, event, null, r._id) ||
        (newestTrace && newestTrace.reported_date > getNewestReportTimestamp(c, ['trace']));
    }
  }

I am convinced it’s a form configuration issue. I’ll try redoing it in the meantime.

Hi @kitsao,
Try adding log to where you’re calling getField. Probably logging in both report and r would be helpful ?

Is it possible that this report is not found and you don’t have a null check in place before passing it forward?

Hi @kitsao, did you get any solution on this or found the reason behind that could be beneficial for community ?

Here is a summary of my findings:

  • The cause of the error was because the report was not available in CouchDB even after syncing. However, the report was available in the client application (PouchDB) and that is why it was possible to console-log it with the profile of the offline user, and not any other user.

  • The observed behavior can be attributed to the can_edit permission, which had been revoked for the role. This meant that the user could not upload their changes to CouchDB - upwards replication simply never occurs , with no indication that anything is wrong as per this cht-core # 6215 comment and this documentation update.

  • After granting the permission, one has to ensure that all documents stuck on the client application are resynced to get to CouchDB and finally to Postgres. Syncing up happens automatically when an affected user syncs again.