Can an RPC result be included in a Supabase select function in Flutter for Data Modeling?

18 Views Asked by At

In my Flutter Web Application, I have the following created tables for an address in Supabase:

-- Table for Region
CREATE TABLE regions (
    id SERIAL PRIMARY KEY,
    region_name TEXT NOT NULL
);

-- Table for Province
CREATE TABLE provinces (
    id SERIAL PRIMARY KEY,
    province_name TEXT NOT NULL,
    region_id INT REFERENCES regions(id) NOT NULL
);

-- Table for Municipalities/Cities
CREATE TABLE municipalities (
    id SERIAL PRIMARY KEY,
    municipality_name TEXT NOT NULL,
    province_id INT REFERENCES provinces(id) NOT NULL
);

-- Table for Barangay (similar to a District or Ward)
CREATE TABLE barangays (
    id SERIAL PRIMARY KEY,
    barangay_name TEXT NOT NULL,
    municipality_id INT REFERENCES municipalities(id) NOT NULL
);

I need to retrieve the complete address by concatenating the results so I created a Remote Procedure Call:

CREATE OR REPLACE FUNCTION get_complete_address(respondent_id TEXT)
RETURNS TEXT AS $$
DECLARE
  address TEXT;
BEGIN
  SELECT CONCAT(COALESCE(r.purok, ''), ' ', b.barangay_name, ', ', m.municipality_name, ', ', p.province_name, ', ', reg.region_name)
  INTO address
  FROM respondents r
  INNER JOIN barangays b ON r.barangay_id = b.id
  INNER JOIN municipalities m ON b.municipality_id = m.id
  INNER JOIN provinces p ON m.province_id = p.id
  INNER JOIN regions reg ON p.region_id = reg.id
  WHERE r.id = respondent_id::uuid;

  RETURN address;
END;
$$ LANGUAGE plpgsql;

Purok is smaller than a barangay and may be null. Testing it in the Supabase Dashboard, it worked using SELECT get_complete_address("<respondent_id>");

I wanted this to be included in the Flutter Data Model and have also updated an existing Repository. This is how the data model for a Respondent is:

class Respondent {
  final String id;
  ...
  final String? purok;
  final int barangayId;
  final String? completeAddress;

  Respondent({
    required this.id,
    ...
    this.purok,
    required this.barangayId,
    this.completeAddress    
  });

  Respondent.fromJson(Map<String, dynamic> json)
      : id = json['id'],
        ...
        purok = json['purok'],
        barangayId = json['barangay_id'],
        completeAddress = json['complete_address'];

  Map<String, dynamic> toJson() => <String, dynamic>{
        'id': id,
        ...
        'purok': purok,
        'barangay_id': barangayId,
        'complete_address' : completeAddress,
      };
}

In my Repository:

Future<Respondent> getRespondent(String id) async {
  try {
    print('Getting respondent');
    final response = await supabase
        .from('respondents')
        .select(
            '*, parent_group:parent_group_id(description), get_complete_address(id) AS complete_address')
        .eq('id', id)
        .single();
    print('Response: $response');
    return Respondent.fromJson(response);
  } catch (error) {
    throw Exception(error);
  }
}

The line 'Getting respondent' is printing, but the next print('Response: $response'); didn't. It means either it has an error in the query, or it was not successfully mapped in the data model. I do not know which is causing the error since it has no error messages. How can I solve or at least try debug this issue? I have been trying to seek Bing/Copilot's assistance, but it keeps showing a deprecated/obsolete function. Thanks in advance.

0

There are 0 best solutions below