# File handling

Jigx stores files as local files on the device and returns the file's URI as the default value. When saving these files to a datasource, you must convert files from the local-uri to base64, data-uri, or buffer. The opposite is true when handling the files returned from the datasource; you must convert them from their saved state (base64, data-uri, or buffer) to a local-uri.

Type of files:

* Images
* Documents

Image files can be used in the following functionality:

<table><thead><tr><th width="238.828125">Data</th><th width="289.21484375">Conversion configuration</th><th>Result</th></tr></thead><tbody><tr><td>REST Provider calls with files</td><td>Add the conversion to the REST function</td><td>GET - incoming<br>SAVE - outgoing<br>CREATE - outgoing<br>UPDATE - outgoing</td></tr><tr><td>SQL Provider calls with files</td><td>Add the conversion to the REST function</td><td>GET - incoming<br>SAVE - outgoing<br>CREATE - outgoing<br>UPDATE - outgoing</td></tr><tr><td>Datasource queries with files</td><td>Add the conversion to the datasource when using Dynamic Data.</td><td>Incoming</td></tr><tr><td>Actions with files</td><td>Add the conversion to the action when saving images and files.</td><td>outgoing</td></tr></tbody></table>

The `conversions` property allows you to configure the file conversion to the required format.

<table><thead><tr><th width="159.19921875">Core structure</th><th></th></tr></thead><tbody><tr><td><code>conversions:</code></td><td><p>This holds an array of properties that should be converted. The following properties control the conversion:</p><ul><li><code>property:</code> The name of the property to convert.</li><li><code>from:</code> Format of the input data. It can be buffer, base64, data-uri, or local-uri.</li><li><code>to:</code> Format of the converted data. It can be base64, data-uri, buffer, or local-uri.</li><li><code>convertHeicToJpg:</code> When set to <code>true</code>, and the file being converted is HEIC, it is converted to JPG.</li></ul><p>Conversions can be set up as a static array of definitions or dynamically as an array returned by an expression. To set up dynamic conversions, use the expression <code>conversions: =@ctx.datasources.conversions</code>, applicable to both local and global actions.</p></td></tr></tbody></table>

Referencing files in a jig - You can access the file using the `state` of the components and properties in a jig, such as [media-field](https://docs.jigx.com/examples/readme/components/media-field) or [avatar-field](https://docs.jigx.com/examples/readme/components/avatar). When referencing files in jigs use the `.state.value` configuration. For example:

* `file: =@ctx.components.profilePicture.state.value`
* `image: =@ctx.components.image.state.value`

## Considerations

* Conversions should be configured within the SQL and REST functions. When the conversion is configured in the function, it stores the data as the 'from' type in the datasource.
* When conversions are done at the datasource level, they are still stored in the datasource as their original value. They are only converted after the fact when requested; however, the datasource value does not change.
* Do not load data back from buffer using the Dynamic Data provider; the file will not show.
* When saving images to Dynamic Data consider the file size. You can reduce the file size in the [media-field](https://docs.jigx.com/examples/readme/components/media-field) by configuring the `imageQuality` property.
* Use `convertHeicToJpg` to ensure images are visible on iOS and Android devices. The property is available for REST and SQL functions, Dynamic Data and actions.

{% hint style="warning" %}
Jigx does not recommend storing images in Dynamic Data (via any conversion), as the max file size per record is 350K.
{% endhint %}

## Examples and code snippets

## Convert incoming data

### REST & SQL function

In the examples below, the file conversions are configured in the REST and SQL (GET) functions to convert the incoming files.

{% tabs %}
{% tab title="rest-function-in" %}

```yaml
provider: DATA_PROVIDER_REST
method: GET
# pdf indicates a generic binary type
format: pdf 
url: https://graph.microsoft.com/v1.0/me/photo/$value
# Add the email input to the output to identify image later in select
useLocalCall: true
outputTransform: $.{"data":$.data,"userId":$.inputs.userId.value} 
parameters:
  accessToken:
    location: header
    required: true
    type: string
    # Use manage.jigx.com to define credentials for your solution.
    value: oauth.microsoft 
  userId:
    type: string
    location: path
    required: true
conversions:
  - property: data
    from: base64
    to: local-uri
```

{% endtab %}

{% tab title="sql-function-in" %}

```yaml
provider: DATA_PROVIDER_SQL
method: query
connection: test-db
query: SELECT TOP(@top) Id, FirstName, LastName, AvatarBase64, AvatarDataUri, AvatarBuffer FROM Employee
parameters:
  top:
    location: input
    required: false
    type: number
    value: 10
conversions:
  - property: AvatarBuffer
    from: buffer
    to: local-uri
  - property: AvatarBase64
    from: base64
    to: local-uri
  - property: AvatarDataUri
    from: data-uri
    to: local-uri
```

{% endtab %}
{% endtabs %}

## Convert outgoing data

### REST & SQL function

In the examples below, the file conversions are configured in the **REST** and **SQL** (SAVE/CREATE/UPDATE) **functions** to convert the files that are outgoing to REST and SQL.

{% tabs %}
{% tab title="rest-function-out" %}

```yaml
provider: DATA_PROVIDER_REST
method: PATCH
url: https://graph.microsoft.com/v1.0/me/photo/$value
useLocalCall: true
parameters:
  accessToken:
    location: header
    required: true
    type: string
    # Use manage.jigx.com to define credentials for your solution.
    value: oauth.microsoft 
  Content-Type:
    location: header
    required: true
    type: string
    # set the content type of the body.
    value: image/jpeg 
  file:
    location: body
    required: true
    type: image
conversions:
  - property: file
    from: local-uri
    to: buffer
```

{% endtab %}

{% tab title="sql-function-out" %}

```yaml
provider: DATA_PROVIDER_SQL
method: execute
connection: test-db
procedure: AddWidget
parameters:
  firstname:
    location: input
    required: true
    type: string
  lastname:
    location: input
    required: true
    type: string
  avatarbase64:
    location: input
    required: true
    type: string
  avatardatauri:
    location: input
    required: true
    type: string
  avatarbuffer:
    location: input
    required: true
    type: file
    encoding: binary
conversions:
  - property: avatarbuffer
    from: local-uri
    to: buffer
  - property: avatarbase64
    from: local-uri
    to: base64
  - property: avatardatauri
    from: local-uri
    to: data-uri
```

{% endtab %}
{% endtabs %}

## Datasource conversion

In this example, the Dynamic Data image file conversion is configured in the datasource to convert the files to be used in the solution.

{% code title="datasource-conversion" %}

```yaml
type: datasource.sqlite
options:
  provider: DATA_PROVIDER_DYNAMIC
  entities:
    - default/category
  query: |
    SELECT id, '$.name', '$.description', '$.image'
    FROM [default/category]
    ORDER BY [name]
  conversions:
    - property: image
      from: base64
      to: local-uri
```

{% endcode %}

## Action image conversion

File conversions in actions can be configured with Dynamic Data, SQL, and REST providers. They can be set up as a static array of definitions or dynamically as an array returned by an expression. To set up dynamic conversions, use the expression `conversions: =@ctx.datasources.conversions`, applicable to both local and global actions.

{% tabs %}
{% tab title="execute-entity-action (static)" %}

```yaml
- type: action.execute-entity
    options:
      title: Save
      provider: DATA_PROVIDER_DYNAMIC
      entity: default/category
      method: save
      data:
        id: =@ctx.jig.inputs.categoryId
        name: =@ctx.components.name.state.value
        description: =@ctx.components.description.state.value
        # reference the image using an expression.
        image: =@ctx.components.image.state.value
      # Static conversion configuration.
      conversions:
        - property: image
          from: local-uri
          to: base64
```

{% endtab %}

{% tab title="execute-entity-action (dynamic)" %}

```yaml
- type: action.execute-entity
    options:
      title: Save
      provider: DATA_PROVIDER_DYNAMIC
      entity: default/category
      method: save
      data:
        id: =@ctx.jig.inputs.categoryId
        name: =@ctx.components.name.state.value
        description: =@ctx.components.description.state.value
        # reference the image using an expression.
        image: =@ctx.components.image.state.value
      # Dynamic conversion configuration.
      conversions: =@ctx.datasources.conversions
```

{% endtab %}

{% tab title="datasource" %}

```yaml
type: datasource.sqlite
options:
  provider: DATA_PROVIDER_DYNAMIC
  entities:
    - default/category
  query: |
    SELECT id, '$.name', '$.description', '$.image'
    FROM [default/category]
    ORDER BY [name]
  conversions:
    - property: image
      from: base64
      to: local-uri
```

{% endtab %}
{% endtabs %}

## Add multiple files with SQL data provider

This example uses the `text-field` with `mediaType: image` and `isMultiple: true` to add multiple images to SQL. The `conversion` of the files is done in the SQL function.

{% tabs %}
{% tab title="sql-add-widget-multiple-function.jigx" %}

```yaml
# Add under function folder
provider: DATA_PROVIDER_SQL
method: execute
connection: SportConnect
procedure: AddMultipleAvatar
parameters:
  avatarbuffer:
    encoding: binary
    location: input
    required: true
    type: file
  description:
    location: input
    required: true
    type: string

conversions:
  - from: local-uri
    property: avatar
    to: buffer
```

{% endtab %}

{% tab title="sql-get-widget-multiple-jigx" %}

```yaml
# Add under function folder
provider: DATA_PROVIDER_SQL
method: query
connection: SportConnect

query: |
  SELECT  
    Id, 
    description,
    Avatar
  FROM avatarMultiConversion

conversions:
  - property: Avatar
    from: buffer
    to: local-uri
```

{% endtab %}

{% tab title="add-widget-mutiple-sql.jigx" %}

```yaml
# Add under jig folder
title: Add Widget Multiple
type: jig.default

onFocus:
  type: action.sync-entities
  options:
    provider: DATA_PROVIDER_SQL
    entities:
      - entity: avatarMultiConversion
        function: sql-get-widget-multiple

datasources:
  allImages:
    type: datasource.sqlite
    options:
      provider: DATA_PROVIDER_LOCAL
      entities:
        - entity: avatarMultiConversion
      query: |
        SELECT
          '$.Id',
          '$.type',
          '$.Avatar'
        FROM [avatarMultiConversion]

children:
  - type: component.form
    instanceId: add-widget-multiple
    options:
      children:
        - instanceId: description
          options:
            label: Description
          type: component.text-field
        - instanceId: avatarbuffer
          options:
            # set for multiple files to be added
            isMultiple: true
            label: Avatar
            mediaType: image
          type: component.media-field
      isDiscardChangesAlertEnabled: false

  - type: component.list
    options:
      data: =@ctx.datasources.allImages
      maximumItemsToRender: 8
      item:
        type: component.list-item
        options:
          title: =@ctx.current.item.type
          leftElement:
            element: image
            text: ""
            uri: =@ctx.current.item.Avatar

actions:
  - children:
      # use execute entites for multiple files to be added
      - type: action.execute-entities
        # Options in error are expected as there are no parameters.
        options:
          title: Add Widget Multiple
          provider: DATA_PROVIDER_SQL
          entity: avatarMultiConversion
          data: |
            =@ctx.components.avatarbuffer.state.value.{
              "description" : @ctx.components.description.state.value 
            , "avatarbuffer" : $ }
          function: sql-add-widget-multiple
          goBack: stay
          method: functionCall
          onSuccess:
            title: Success
```

{% endtab %}
{% endtabs %}

## Convert HEIC to JPEG

In this example, the file conversion is configured in the REST function to convert the files that are outgoing via REST. `convertHeicToJpg` is configured to `true` to convert HEIC images to JPEG which ensures images are visible on iOS and Android devices. The property is available REST and SQL functions, Dynamic Data and actions.

```yaml
provider: DATA_PROVIDER_REST
method: PATCH
url: https://graph.microsoft.com/v1.0/me/photo/$value
useLocalCall: true
parameters:
  accessToken:
    location: header
    required: true
    type: string
    # Use manage.jigx.com to define credentials for your solution.
    value: oauth.microsoft 
  Content-Type:
    location: header
    required: true
    type: string
    # set the content type of the body.
    value: image/jpeg 
  file:
    location: body
    required: true
    type: image
conversions:
  - property: file
    from: local-uri
    to: buffer
    convertHeicToJpg: true
```

### See Also

* [Example converting local-uri to buffer in SQL function](https://docs.jigx.com/examples/readme/components/media-field#convert-files-in-sql-function)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.jigx.com/building-apps-with-jigx/data/file-handling.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
