Home > OS >  Parsing a list of images from NOTION database to flutter app
Parsing a list of images from NOTION database to flutter app

Time:09-05

I am trying to display Notion content such as texts, dates, booleans and images on flutter app.. For texts, dates, and booleans, everything is working.. but I am stuck at displaying images. Please kindly take a look at my JSON file and my code.. and let me know where I am doing wrong..

JSON file that I got from my Notion database

{
  "object": "list",
  "results": [
    {
      "object": "page",
      "id": "0f2aad20-225a-4d40-b853-fb5943e01636",
      "created_time": "2022-09-01T05:14:00.000Z",
      "last_edited_time": "2022-09-03T09:56:00.000Z",
      "created_by": {
        "object": "user",
        "id": "33138aa4-0670-49f9-a118-daaef0698369"
      },
      "last_edited_by": {
        "object": "user",
        "id": "33138aa4-0670-49f9-a118-daaef0698369"
      },
      "cover": null,
      "icon": null,
      "parent": {
        "type": "database_id",
        "database_id": "f24cee3c-bd2f-466a-bc5f-a505e83b348f"
      },
      "archived": false,
      "properties": {
        "Price Range": {
          "id": "BiJQ",
          "type": "select",
          "select": {
            "id": "]erF",
            "name": "< 2000 Lakh",
            "color": "default"
          }
        },
        "On Market": {
          "id": "Bxp`",
          "type": "checkbox",
          "checkbox": false
        },
        "Longitude ": {
          "id": "CGYh",
          "type": "number",
          "number": 96.113146
        },
        "Asking Price in Lakh": {
          "id": "Gv}}",
          "type": "number",
          "number": 590
        },
        "Township": {
          "id": "MP}=",
          "type": "select",
          "select": {
            "id": "qwfy",
            "name": "Mingaladon - YGN",
            "color": "default"
          }
        },
        "Owner Phone": {
          "id": "Mqhp",
          "type": "phone_number",
          "phone_number": "09448840549"
        },
        "Images": {
          "id": "OLC;",
          "type": "files",
          "files": [
            {
              "name": "31_AUG-22.jpg",
              "type": "file",
              "file": {
                "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/04b39e7e-c2c4-4ccd-a653-348933fa613e/31_AUG-22.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45/20220903/us-west-2/s3/aws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=2db13c256bfd191fc3fbc0941438a4a1c75a8da128b6f69b6e2a63002140327b&X-Amz-SignedHeaders=host&x-id=GetObject",
                "expiry_time": "2022-09-03T11:29:52.168Z"
              }
            },
            {
              "name": "31_AUG-21.jpg",
              "type": "file",
              "file": {
                "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/06ce697d-af96-4f3e-b26e-bc092cacfdf8/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45/20220903/us-west-2/s3/aws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=33d5c21d71113008f3fbc4f95bf311515e4d42a3eb1f8c6c10fccc355e4e2d9a&X-Amz-SignedHeaders=host&x-id=GetObject",
                "expiry_time": "2022-09-03T11:29:52.209Z"
              }
            },
            {
              "name": "31_AUG-23.jpg",
              "type": "file",
              "file": {
                "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/32ec9466-fe8a-4eb9-8c1b-0d0abbe8637b/31_AUG-23.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45/20220903/us-west-2/s3/aws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=059545c77b9a2330483d34292d2b7e4503d3e9f7ceac67cd44f63d56d6d8a0f0&X-Amz-SignedHeaders=host&x-id=GetObject",
                "expiry_time": "2022-09-03T11:29:52.271Z"
              }
            }
          ]
        },
        "Zone": {
          "id": "O_ui",
          "type": "select",
          "select": {
            "id": "bWGg",
            "name": "13",
            "color": "default"
          }
        },
        "Progress": {
          "id": "P<{M",
          "type": "multi_select",
          "multi_select": []
        },
        "Category": {
          "id": "PM^A",
          "type": "select",
          "select": {
            "id": "kLgI",
            "name": "Residential",
            "color": "default"
          }
        },
        "Status": {
          "id": "R{]l",
          "type": "select",
          "select": {
            "id": ":huS",
            "name": "For Sale",
            "color": "default"
          }
        },
        "Latitude ": {
          "id": "TUmm",
          "type": "number",
          "number": 16.955839
        },
        "Flooring": {
          "id": "U?S]",
          "type": "rich_text",
          "rich_text": []
        },
        "Bathroom": {
          "id": "WPEe",
          "type": "number",
          "number": 1
        },
        "Price Per Sqft": {
          "id": "\:lg",
          "type": "number",
          "number": 21000
        },
        "Address": {
          "id": "]Sz|",
          "type": "rich_text",
          "rich_text": [
            {
              "type": "text",
              "text": {
                "content": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
                "link": null
              },
              "annotations": {
                "bold": false,
                "italic": false,
                "strikethrough": false,
                "underline": false,
                "code": false,
                "color": "default"
              },
              "plain_text": "Mingalardon, ဝါယာလက် , တောတိုက်ရပ်ကွက်, အမှတ် ၇/၄၉",
              "href": null
            }
          ]
        },
        "Type": {
          "id": "^>@F",
          "type": "select",
          "select": {
            "id": "Hb_}",
            "name": "House",
            "color": "default"
          }
        },
        "State": {
          "id": "^}P`",
          "type": "select",
          "select": {
            "id": ":fMv",
            "name": "YGN",
            "color": "default"
          }
        },
        "Year Built": {
          "id": "a\\e",
          "type": "number",
          "number": 2014
        },
        "Data Source": {
          "id": "awp[",
          "type": "select",
          "select": {
            "id": "Ohch",
            "name": "Facebook",
            "color": "default"
          }
        },
        "Electricity": {
          "id": "bCpc",
          "type": "select",
          "select": {
            "id": "=^]Q",
            "name": "1 Single",
            "color": "default"
          }
        },
        "Cover Photo": {
          "id": "bDDW",
          "type": "files",
          "files": [
            {
              "name": "31_AUG-21.jpg",
              "type": "file",
              "file": {
                "url": "https://s3.us-west-2.amazonaws.com/secure.notion-static.com/b2784859-34d3-41c2-a88a-3311d8886804/31_AUG-21.jpg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45/20220903/us-west-2/s3/aws4_request&X-Amz-Date=20220903T102952Z&X-Amz-Expires=3600&X-Amz-Signature=eb7ab8e22917357922dfa939c250c5106f8e496888b564f17c622d804045f4ff&X-Amz-SignedHeaders=host&x-id=GetObject",
                "expiry_time": "2022-09-03T11:29:52.297Z"
              }
            }
          ]
        },
        "Contact": {
          "id": "d_^>",
          "type": "relation",
          "relation": []
        },
        "Car Parking": {
          "id": "gIBP",
          "type": "number",
          "number": 2
        },
        "Water System": {
          "id": "gfRJ",
          "type": "multi_select",
          "multi_select": [
            {
              "id": "08a52b0a-cbbf-4e7d-8756-c2edb40a8ed9",
              "name": "ဂျိုးဖြူရေ",
              "color": "gray"
            }
          ]
        },
        "Sold Date": {
          "id": "giQA",
          "type": "date",
          "date": null
        },
        "Air Con": {
          "id": "mP]d",
          "type": "number",
          "number": 0
        },
        "Bedrooms": {
          "id": "ptfQ",
          "type": "select",
          "select": {
            "id": "O}`U",
            "name": "3",
            "color": "default"
          }
        },
        "Owner Direct": {
          "id": "py@O",
          "type": "checkbox",
          "checkbox": false
        },
        "Lot Size (Sqft)": {
          "id": "t:wQ",
          "type": "number",
          "number": 2795
        },
        "Type of Ownership": {
          "id": "vgED",
          "type": "select",
          "select": {
            "id": "37a4fbaa-955f-48d0-9a4d-4f5a28a8ca9a",
            "name": "အရပ်စာချုပ်",
            "color": "red"
          }
        },
        "Added Time": {
          "id": "x;yd",
          "type": "last_edited_time",
          "last_edited_time": "2022-09-03T09:56:00.000Z"
        },
        "ခြံအကျယ် (ပေ)": {
          "id": "z==@",
          "type": "rich_text",
          "rich_text": [
            {
              "type": "text",
              "text": {
                "content": "43x65",
                "link": null
              },
              "annotations": {
                "bold": false,
                "italic": false,
                "strikethrough": false,
                "underline": false,
                "code": false,
                "color": "default"
              },
              "plain_text": "43x65",
              "href": null
            }
          ]
        },
        "Structure": {
          "id": "|j^r",
          "type": "select",
          "select": {
            "id": "ad149505-37a9-4464-8d13-7ff1e34cef3f",
            "name": "ပျဉ်ထောင်အိမ်",
            "color": "blue"
          }
        },
        "Property Title": {
          "id": "|n?>",
          "type": "rich_text",
          "rich_text": [
            {
              "type": "text",
              "text": {
                "content": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
                "link": null
              },
              "annotations": {
                "bold": false,
                "italic": false,
                "strikethrough": false,
                "underline": false,
                "code": false,
                "color": "default"
              },
              "plain_text": "မင်္ဂလာဒုံမြို့နယ်တောတိုက်ရပ်ကွက် ရှိ အိမ်လေးတစ်လုံးရောင်းရန်ရှိ",
              "href": null
            }
          ]
        },
        "360 Photo ": {
          "id": "~yOp",
          "type": "url",
          "url": "https://kuula.co/share/collection/7vSsM?logo=0&info=1&fs=1&vr=0&sd=1&thumbs=1"
        },
        "Name": {
          "id": "title",
          "type": "title",
          "title": [
            {
              "type": "text",
              "text": {
                "content": "YGN-13C-06",
                "link": null
              },
              "annotations": {
                "bold": false,
                "italic": false,
                "strikethrough": false,
                "underline": false,
                "code": false,
                "color": "default"
              },
              "plain_text": "YGN-13C-06",
              "href": null
            }
          ]
        }
      },
      "url": "https://www.notion.so/YGN-13C-06-0f2aad20225a4d40b853fb5943e01636"
    },

How I get data from Notion

class NotionAPI {
  final http.Client _client;
  static const String _baseUrl = 'https://api.notion.com/v1/';

  NotionAPI({http.Client? client}) : _client = client ?? http.Client();

  void dispose() {
    _client.close();
  }

  Future<List<NotionPropertyModel>> getProperties() async {
    try {
      final url =
          '${_baseUrl}databases/${dotenv.env['NOTION_DATABASE_ID']}/query';
      final response = await _client.post(
        Uri.parse(url),
        headers: {
          HttpHeaders.authorizationHeader:
              'Bearer ${dotenv.env['NOTION_API_KEY']}',
          'Notion-Version': '2022-06-28',
        },
      );
      if (response.statusCode == 200) {
        final data = jsonDecode(response.body) as Map<String, dynamic>;
        return (data['results'] as List)
            .map((e) => NotionPropertyModel.fromMap(e))
            .toList()
          ..sort((a, b) => b.date.compareTo(a.date));
      } else {
        throw const Failure(message: 'Something went wrong..STW!');
      }
    } catch (_) {
      throw const Failure(message: 'Something went wrong..    !');
    }
  }
}

My fromJson method

  factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
    final properties = map['properties'] as Map<String, dynamic>;
    final dateStr = properties['Date']?['date']?['start'];
    return NotionPropertyModel(
      pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
      date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
      dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
      ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
      priceInLakh:
          (properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
      coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],
    );
  }

How I display on the screen

      child: Column(
        children: [
          Image.network(itemData.coverPhoto),
          Text(itemData.pptID),
          Text(itemData.dataSource),
          if (itemData.ownerDirect == true)
            const Text(
              'Owner Direct',
              style: TextStyle(fontSize: 20),
            )
        ],
      ),

CodePudding user response:

Your cover image is a list of file so change this:

coverPhoto: properties['Cover Photo']?['files']?['file']?['url'],

to

factory NotionPropertyModel.fromMap(Map<String, dynamic> map) {
    final properties = map['properties'] as Map<String, dynamic>;
    final dateStr = properties['Date']?['date']?['start'];
    List coverList = properties['Cover Photo']?['files'] ?? [];
    return NotionPropertyModel(
      pptID: properties['Name']?['title']?[0]?['plain_text'] ?? '?',
      date: dateStr != null ? DateTime.parse(dateStr) : DateTime.now(),
      dataSource: properties['Data Source']?['select']?['name'] ?? 'Any',
      ownerDirect: properties['Owner Direct']?['checkbox'] as bool,
      priceInLakh:
          (properties['Asking Price in Lakh']?['number'] ?? 0).toDouble(),
      coverPhoto: (coverList != null && coverList.isNotEmpty) ? coverList[0]['file']?['url'] : '',
    );
  }
  • Related