platform/packages/validate/example/main.dart

115 lines
3.2 KiB
Dart
Raw Normal View History

import 'dart:async';
2019-10-17 00:13:36 +00:00
import 'package:angel_framework/angel_framework.dart';
import 'package:angel_framework/http.dart';
import 'package:angel_validate/angel_validate.dart';
import 'package:http_parser/http_parser.dart';
import 'package:logging/logging.dart';
import 'package:pretty_logging/pretty_logging.dart';
2018-12-10 17:51:10 +00:00
Future<void> main() async {
2019-10-17 00:13:36 +00:00
Logger.root
..level = Level.ALL
..onRecord.listen(prettyLog);
var app = Angel(logger: Logger('angel_validate'));
var http = AngelHttp(app);
2019-10-17 00:54:38 +00:00
var todos = <Todo>[];
2019-10-17 00:13:36 +00:00
2019-10-17 00:54:38 +00:00
/// We can combine fields into a form; this is most
/// useful when we immediately deserialize the form into
/// something else.
2019-10-17 00:13:36 +00:00
var todoForm = Form(fields: [
2019-10-17 00:54:38 +00:00
TextField('text'),
BoolField('is_complete'),
2019-10-17 00:13:36 +00:00
]);
2019-10-17 00:54:38 +00:00
/// We can directly use a `Form` to deserialize a
/// request body into a `Map<String, dynamic>`.
///
/// By calling `deserialize` or `decode`, we can populate
/// concrete Dart objects.
app.post('/', (req, res) async {
var todo = await todoForm.deserialize(req, Todo.fromMap);
todos.add(todo);
await res.redirect('/');
});
/// You can also use `Field`s to read directly from the
/// request, without `as` casts.
///
/// In this handler, we read the value of `name` from the query.
app.get('/hello', (req, res) async {
var nameField = TextField('name');
var name = await nameField.getValue(req, query: true);
return 'Hello, $name!';
});
/// Simple page displaying a form and some state.
2019-10-17 00:13:36 +00:00
app.get('/', (req, res) {
res
..contentType = MediaType('text', 'html')
..write('''
<!doctype html>
<html>
<body>
2019-10-17 00:54:38 +00:00
<h1>angel_validate</h1>
<ul>
${todos.map((t) {
return '<li>${t.text} (isComplete=${t.isComplete})</li>';
}).join()}
</ul>
2019-10-17 00:13:36 +00:00
<form method="POST">
<label for="text">Text:</label>
<input id="text" name="text">
<br>
<label for="is_complete">Complete?</label>
<input id="is_complete" name="is_complete" type="checkbox">
<br>
2019-10-17 00:54:38 +00:00
<button type="submit">Add Todo</button>
2019-10-17 00:13:36 +00:00
</form>
</body>
</html>
''');
});
2020-05-04 18:35:16 +00:00
// You can use a [MapField] to embed one [Form] with another.
// In this example, we embed the [todoForm], but also call `.deserialize`,
// so that the final value we see is a [Todo] instance, rather than a [Map].
app.post('/map_field', (req, res) async {
var form = Form(fields: [
2020-05-04 18:35:16 +00:00
MapField('todo', todoForm).deserialize(Todo.fromMap),
]);
2020-05-04 18:35:16 +00:00
var data = await form.validate(req);
var b = StringBuffer();
b.write(data);
return b.toString();
});
2019-10-17 00:13:36 +00:00
app.fallback((req, res) => throw AngelHttpException.notFound());
app.errorHandler = (e, req, res) {
res.writeln('Error ${e.statusCode}: ${e.message}');
for (var error in e.errors) {
res.writeln('* $error');
}
};
await http.startServer('127.0.0.1', 3011);
2019-10-17 00:54:38 +00:00
print('Listening at ${http.uri}');
2019-10-17 00:13:36 +00:00
}
class Todo {
final String text;
final bool isComplete;
Todo(this.text, this.isComplete);
static Todo fromMap(Map map) {
return Todo(map['text'] as String, map['is_complete'] as bool);
}
2020-05-04 18:35:16 +00:00
@override
String toString() => 'Todo($text, $isComplete)';
2019-10-17 00:13:36 +00:00
}