Reputation: 81
like how to fix boilerplate code in separate file and use it in ui pages.
I Need to declare this uri variable in separate file and access across over all pages:
static var uri = "https://xxx/xxx/web_api/public";
static BaseOptions options = BaseOptions(
baseUrl: uri,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
// ignore: missing_return
validateStatus: (code) {
if (code >= 200) {
return true;
}
}); static Dio dio = Dio(options);
In UI page i have to declare that uri variable and BaseOption variable in this future function:
Future<dynamic> _loginUser(String email, String password) async {
try {
Options options = Options(
headers: {"Content-Type": "application/json"},
);
Response response = await dio.post('/login',
data: {
"email": email,
"password": password,
"user_type": 2,
"status": 1
},
options: options);
if (response.statusCode == 200 || response.statusCode == 201) {
var responseJson = json.decode(response.data);
return responseJson;
} else if (response.statusCode == 401) {
throw Exception("Incorrect Email/Password");
} else
throw Exception('Authentication Error');
} on DioError catch (exception) {
if (exception == null ||
exception.toString().contains('SocketException')) {
throw Exception("Network Error");
} else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
exception.type == DioErrorType.CONNECT_TIMEOUT) {
throw Exception(
"Could'nt connect, please ensure you have a stable network.");
} else {
return null;
}
}
}
Upvotes: 6
Views: 29155
Reputation: 6777
I set domain and env values in .env
file. Then I read it using dotenv pacckage
local.env
env=local
apidomain=localhost:8000
dev.env
env=dev
apidomain=xyz.com
Following function gives url (http or https) based on environment. It uses domain based on environment too
import 'package:flutter_dotenv/flutter_dotenv.dart';
Uri getCompleteUrl({required String url}) {
// if local env then http else https url
String domain = dotenv.get('apidomain'); // localhost:8000 or xyz.com
if (dotenv.get('env') == 'local') {
return Uri.http(domain, url);
} else {
return Uri.https(domain, url);
}
}
Upvotes: 0
Reputation: 2106
You can create app_config.dart file and manage different environments like below:
const _baseUrl = "baseUrl";
enum Environment { dev, stage, prod }
Map<String, dynamic> _config;
void setEnvironment(Environment env) {
switch (env) {
case Environment.dev:
_config = devConstants;
break;
case Environment.stage:
_config = stageConstants;
break;
case Environment.prod:
_config = prodConstants;
break;
}
}
dynamic get apiBaseUrl {
return _config[_baseUrl];
}
Map<String, dynamic> devConstants = {
_baseUrl: "https://devapi.xyz.com/",
};
Map<String, dynamic> stageConstants = {
_baseUrl: "https://api.stage.com/",
};
Map<String, dynamic> prodConstants = {
_baseUrl: "https://api.production.com/",
};
Upvotes: 10
Reputation: 2757
Maybe instead of statically declaring your Dio
object you could put it in a class, also put your loginUser
function in there, and use Provider
to obtain that object to call it where you need it.
class Api {
static var uri = "https://xxx/xxx/web_api/public";
static BaseOptions options = BaseOptions(
baseUrl: uri,
responseType: ResponseType.plain,
connectTimeout: 30000,
receiveTimeout: 30000,
// ignore: missing_return
validateStatus: (code) {
if (code >= 200) {
return true;
}
});
Dio dio = Dio(options);
Future<dynamic> loginUser(String email, String password) async {
try {
RequestOptions options = RequestOptions(
headers: {"Content-Type": "application/json"},
);
Response response = await dio.post('/login',
data: {
"email": email,
"password": password,
"user_type": 2,
"status": 1
},
options: options);
//the rest of your code here
}
https://pub.dev/packages/provider
Provider(
create: (_) => Api(),
child: ...
)
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html
YourWidget(
child: Consumer<Api>(
builder: (context, api, child) {
return FutureBuilder<dynamic>(
future: api.loginUser('[email protected]', 'user_password')
builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) {
if (snapshot.hasData) {
//show a widget based on snapshot.data
} else {
//show another widget
}
}
},
),
)
Upvotes: 2