Skip to content

Improvements to code examples #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Apr 2, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Improvements to code examples
  • Loading branch information
Hein committed Mar 31, 2025
commit b12731f91b84a5ececd3c81a070ed0b2a97830ab
122 changes: 96 additions & 26 deletions client-sdk-references/flutter.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -58,12 +58,11 @@
Similar functionality exists in the [CLI](/usage/tools/cli).

</Info>
The types available are `text`, `integer` and `real`. These should map directly to the values produced by the [Sync Rules](/usage/sync-rules). If a value doesn't match, it is cast automatically. For details on how Postgres types are mapped to the types below, see the section on [Types](/usage/sync-rules/types) in the _Sync Rules_ documentation.

Check warning on line 61 in client-sdk-references/flutter.mdx

View check run for this annotation

Mintlify / Mintlify Validation - vale-spellcheck

client-sdk-references/flutter.mdx#L61

Did you really mean '_Sync'?

Check warning on line 61 in client-sdk-references/flutter.mdx

View check run for this annotation

Mintlify / Mintlify Validation - vale-spellcheck

client-sdk-references/flutter.mdx#L61

Did you really mean 'Rules_'?

**Example**:

```dart
// lib/models/schema.dart
```dart lib/models/schema.dart
import 'package:powersync/powersync.dart';

const schema = Schema(([
Expand Down Expand Up @@ -101,10 +100,12 @@

**Example**:

```dart
import 'package:powersync/powersync.dart';
import 'package:path_provider/path_provider.dart';
```dart lib/util/powersync.dart
import 'package:demo/models/schema.dart';
import 'package:demo/util/my_backend_connector.dart';
import 'package:path/path.dart';
import 'package:path_provider/path_provider.dart';
import 'package:powersync/powersync.dart';

openDatabase() async {
final dir = await getApplicationSupportDirectory();
Expand All @@ -119,9 +120,46 @@

Once you've instantiated your PowerSync database, you will need to call the [connect()](https://pub.dev/documentation/powersync/latest/powersync/PowerSyncDatabase/connect.html) method to activate it. This method requires the backend connector that will be created in the next step.

```dart
// Uses the backend connector that will be created in the next step
db.connect(connector: MyBackendConnector(db));
```dart lib/main.dart
import 'package:flutter_counter/util/my_backend_connector.dart';
import 'package:flutter_counter/util/powersync.dart';

Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();

await openDatabase();
runApp(const DemoApp());
}

class DemoApp extends StatefulWidget {
const DemoApp({super.key});

@override
State<DemoApp> createState() => _DemoAppState();
}

class _DemoAppState extends State<DemoApp> {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Demo',
home: // TODO: Implement your own UI here.
// You could listen for authentication state changes to connect or disconnect from PowerSync
StreamBuilder(
stream: // TODO: some stream,
builder: (ctx, snapshot) {,
// TODO: implement your own condition here
if ( ... ) {
// Uses the backend connector that will be created in the next step
db.connect(connector: MyBackendConnector());
// TODO: implement your own UI here
}
},
)
);
}
}

```

### 3\. Integrate with your Backend
Expand All @@ -141,10 +179,8 @@

**Example**:

```dart
```dart lib/util/my_backend_connector.dart
import 'package:powersync/powersync.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart';

late PowerSyncDatabase db;

Expand All @@ -161,18 +197,40 @@

// See example implementation here: https://pub.dev/documentation/powersync/latest/powersync/DevConnector/fetchCredentials.html

return {
endpoint: '[Your PowerSync instance URL or self-hosted endpoint]',
// Use a development token (see Authentication Setup https://docs.powersync.com/installation/authentication-setup/development-tokens) to get up and running quickly
token: 'An authentication token'
};
return PowerSyncCredentials(
endpoint: 'https://xxxxxx.powersync.journeyapps.com',
token: 'An authentication token'
);
}

// Implement uploadData to send local changes to your backend service
// You can omit this method if you only want to sync data from the server to the client
// See example implementation here: https://docs.powersync.com/client-sdk-references/flutter#3-integrate-with-your-backend
@override
Future<void> uploadData(PowerSyncDatabase database) async {
// Implement uploadData to send local changes to your backend service
// You can omit this method if you only want to sync data from the server to the client
// This function is called whenever there is data to upload, whether the
// device is online or offline.
// If this call throws an error, it is retried periodically.

final transaction = await database.getNextCrudTransaction();
if (transaction == null) {
return;
}

// See example implementation here: https://docs.powersync.com/client-sdk-references/flutter#3-integrate-with-your-backend
// The data that needs to be changed in the remote db
for (var op in transaction.crud) {
switch (op.op) {
case UpdateType.put:
// TODO: Instruct your backend API to CREATE a record
case UpdateType.patch:
// TODO: Instruct your backend API to PATCH a record
case UpdateType.delete:
//TODO: Instruct your backend API to DELETE a record
}
}

// Completes the transaction and moves onto the next one
await transaction.complete();
}
}

Expand All @@ -193,8 +251,11 @@

The [get](https://pub.dev/documentation/powersync/latest/sqlite_async/SqliteQueries/get.html) method executes a read-only (SELECT) query and returns a single result. It throws an exception if no result is found. Use [getOptional](https://pub.dev/documentation/powersync/latest/sqlite_async/SqliteQueries/getOptional.html) to return a single optional result (returns `null` if no result is found).

```dart
// Find a list item by ID
The following is an example of selecting a list item by ID
```dart lib/widgets/todo_item_widget.dart
import 'package:demo/util/my_backend_connector.dart';
import 'package:demo/models/todo_list.dart';

Future<TodoList> find(id) async {
final result = await db.get('SELECT * FROM lists WHERE id = ?', [id]);
return TodoList.fromRow(result);
Expand All @@ -205,19 +266,25 @@

The [getAll](https://pub.dev/documentation/powersync/latest/sqlite_async/SqliteQueries/getAll.html) method returns a set of rows from a table.

```dart
/// Get all list IDs
```dart lib/widgets/lists_widget.dart
import 'package:flutter_counter/util/my_backend_connector.dart';
import 'package:powersync/sqlite3.dart';

Future<List<String>> getLists() async {
ResultSet results = await db.getAll('SELECT id FROM lists WHERE id IS NOT NULL');
List<String> ids = results.map((row) => row['id'] as String).toList();
return ids;
}
```

### Watching Queries (PowerSync.watch)

The [watch](https://pub.dev/documentation/powersync/latest/sqlite_async/SqliteQueries/watch.html) method executes a read query whenever a change to a dependent table is made.

```dart
```dart lib/widgets/customers_widget.dart
import 'package:flutter/material.dart';
import 'package:demo/util/my_backend_connector.dart';

StreamBuilder(
// You can watch any SQL query
stream: db.watch('SELECT * FROM customers ORDER BY id asc'),
Expand All @@ -229,14 +296,17 @@
return const Center(child: CircularProgressIndicator());
}
},
)
);
```

### Mutations (PowerSync.execute)

The [execute](https://pub.dev/documentation/powersync/latest/powersync/PowerSyncDatabase/execute.html) method can be used for executing single SQLite write statements.

```dart
```dart lib/widgets/customers_widget.dart
import 'package:flutter/material.dart';
import 'package:demo/util/my_backend_connector.dart';

FloatingActionButton(
onPressed: () async {
await db.execute(
Expand Down