Skip to content

Commit

Permalink
Comunicação HTTP: Flutter com web API
Browse files Browse the repository at this point in the history
  • Loading branch information
muriloao committed Jul 28, 2020
1 parent 1f600c9 commit 454ca8d
Show file tree
Hide file tree
Showing 12 changed files with 299 additions and 19 deletions.
2 changes: 1 addition & 1 deletion .flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"http_interceptor","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\http_interceptor-0.1.1\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.1.7+2\\\\","dependencies":[]}],"android":[{"name":"http_interceptor","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\http_interceptor-0.1.1\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.1.7+2\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"http_interceptor","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-07-28 09:47:41.675852","version":"1.17.5"}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"http_interceptor","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\http_interceptor-0.1.1\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.1.7+2\\\\","dependencies":[]}],"android":[{"name":"http_interceptor","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\http_interceptor-0.1.1\\\\","dependencies":[]},{"name":"sqflite","path":"C:\\\\flutter\\\\.pub-cache\\\\hosted\\\\pub.dartlang.org\\\\sqflite-1.1.7+2\\\\","dependencies":[]}],"macos":[],"linux":[],"windows":[],"web":[]},"dependencyGraph":[{"name":"http_interceptor","dependencies":[]},{"name":"sqflite","dependencies":[]}],"date_created":"2020-07-28 09:51:18.786436","version":"1.17.5"}
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
A new Flutter project.

Study application
Held in the course [Flutter com web API: integrando sua app mobile](https://cursos.alura.com.br/course/flutter-web-api)
Held in the course [Comunicação HTTP: Flutter com web API](https://cursos.alura.com.br/course/flutter-comunicacao-http)
10 changes: 7 additions & 3 deletions lib/components/progress.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'package:flutter/material.dart';

class Progress extends StatelessWidget {

final String message;

Progress({this.message = 'Loading'});
Progress({
this.message = 'Loading',
});

@override
Widget build(BuildContext context) {
Expand All @@ -14,7 +15,10 @@ class Progress extends StatelessWidget {
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
CircularProgressIndicator(),
Text(message)
Padding(
padding: const EdgeInsets.only(top: 8.0),
child: Text(message, style: TextStyle(fontSize: 16.0),),
),
],
),
);
Expand Down
108 changes: 108 additions & 0 deletions lib/components/response_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
import 'package:flutter/material.dart';

class ResponseDialog extends StatelessWidget {
final String title;
final String message;
final String buttonText;
final IconData icon;
final Color colorIcon;

ResponseDialog({
this.title = "",
this.message = "",
this.icon,
this.buttonText = 'Ok',
this.colorIcon = Colors.black,
});

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Visibility(
child: Text(title),
visible: title.isNotEmpty,
),
content: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[
Visibility(
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Icon(
icon,
size: 64,
color: colorIcon,
),
),
visible: icon != null,
),
Visibility(
child: Padding(
padding: const EdgeInsets.only(top: 16.0),
child: Text(
message,
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 24.0,
),
),
),
visible: message.isNotEmpty,
)
],
),
actions: <Widget>[
FlatButton(
child: Text(buttonText),
onPressed: () => Navigator.pop(context),
)
],
);
}
}

class SuccessDialog extends StatelessWidget {
final String title;
final String message;
final IconData icon;

SuccessDialog(
this.message, {
this.title = 'Success',
this.icon = Icons.done,
});

@override
Widget build(BuildContext context) {
return ResponseDialog(
title: title,
message: message,
icon: icon,
colorIcon: Colors.green,
);
}
}

class FailureDialog extends StatelessWidget {
final String title;
final String message;
final IconData icon;

FailureDialog(
this.message, {
this.title = 'Failure',
this.icon = Icons.warning,
});

@override
Widget build(BuildContext context) {
return ResponseDialog(
title: title,
message: message,
icon: icon,
colorIcon: Colors.red,
);
}
}
46 changes: 46 additions & 0 deletions lib/components/transaction_auth_dialog.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import 'package:flutter/material.dart';

class TransactionAuthDialog extends StatefulWidget {
final Function(String password) onConfirm;

TransactionAuthDialog({
@required this.onConfirm,
});

@override
_TransactionAuthDialogState createState() => _TransactionAuthDialogState();
}

class _TransactionAuthDialogState extends State<TransactionAuthDialog> {

final TextEditingController _passwordController = TextEditingController();

@override
Widget build(BuildContext context) {
return AlertDialog(
title: Text('Authenticate'),
content: TextField(
controller: _passwordController,
obscureText: true,
maxLength: 4,
decoration: InputDecoration(border: OutlineInputBorder()),
textAlign: TextAlign.center,
keyboardType: TextInputType.number,
style: TextStyle(fontSize: 64, letterSpacing: 24),
),
actions: <Widget>[
FlatButton(
onPressed: () => Navigator.pop(context),
child: Text('Cancel'),
),
FlatButton(
onPressed: () {
widget.onConfirm(_passwordController.text);
Navigator.pop(context);
},
child: Text('Confirm'),
),
],
);
}
}
3 changes: 2 additions & 1 deletion lib/http/webclient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ import 'interceptors/logging_interceptor.dart';

final Client client = HttpClientWithInterceptor.build(
interceptors: [LoggingInterceptor()],
requestTimeout: Duration(seconds: 5),
);

const String baseUrl = 'http://192.168.20.249:8080/transactions';
const String baseUrl = 'http://192.168.58.1:8080/transactions';


32 changes: 28 additions & 4 deletions lib/http/webclients/transaction_webclient.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,24 +7,48 @@ import 'package:http/http.dart';
class TransactionWebClient {
Future<List<Transaction>> findAll() async {
final Response response =
await client.get(baseUrl).timeout(Duration(seconds: 5));
await client.get(baseUrl);
final List<dynamic> decodedJson = jsonDecode(response.body);
return decodedJson
.map((dynamic json) => Transaction.fromJson(json))
.toList();
}

Future<Transaction> save(Transaction transaction) async {
Future<Transaction> save(Transaction transaction, String password) async {
final String transactionJson = jsonEncode(transaction.toJson());

await Future.delayed(Duration(seconds: 2));

final Response response = await client.post(baseUrl,
headers: {
'Content-type': 'application/json',
'password': '1000',
'password': password,
},
body: transactionJson);

return Transaction.fromJson(jsonDecode(response.body));
if (response.statusCode == 200) {
return Transaction.fromJson(jsonDecode(response.body));
}

throw HttpException(_getMessage(response.statusCode));
}

String _getMessage(int statusCode) {
if(_statusCodeResponses.containsKey(statusCode)){
return _statusCodeResponses[statusCode];
}
return 'unknown error';
}

static final Map<int, String> _statusCodeResponses = {
400: 'there was an error submitting transaction',
401: 'authentication failed',
409: 'transaction already exists'
};
}

class HttpException implements Exception {
final String message;

HttpException(this.message);
}
1 change: 1 addition & 0 deletions lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import 'package:bytebank/screens/dashboard.dart';
import 'package:flutter/material.dart';
import 'package:uuid/uuid.dart';

void main() {
runApp(BytebankApp());
Expand Down
4 changes: 4 additions & 0 deletions lib/models/transaction.dart
Original file line number Diff line number Diff line change
@@ -1,20 +1,24 @@
import 'contact.dart';

class Transaction {
final String id;
final double value;
final Contact contact;

Transaction(
this.id,
this.value,
this.contact,
);

Transaction.fromJson(Map<String, dynamic> json) :
id = json['id'],
value = json['value'],
contact = Contact.fromJson(json['contact']);

Map<String, dynamic> toJson() =>
{
'id' : id,
'value': value,
'contact': contact.toJson(),
};
Expand Down
Loading

0 comments on commit 454ca8d

Please sign in to comment.