TypeError: html.window.navigator.geolocation[$watchPosition] is not a function - angular-dart

I am getting error
TypeError: html.window.navigator.geolocation[$watchPosition] is not a function
during execution of below function in one of the component. Do I need to do any setup before calling methods in window.navigator.geolocation?
#override
void ngOnInit() {
if (window.navigator.geolocation != null) {
//try {
window.navigator.geolocation.watchPosition(enableHighAccuracy: true).listen(
(position) => userPosition = position,
onError: (Error er) {});
//} catch (e) {
//}
}
}

Related

Exception throw flutter

am learning api integration with bloc, these exception is been thrown when data is trying to fetch, for loadingstate i assigned a progressindicator then after that state when trying to get data,these exeption is been thrown ,pls helpenter image description here
as per the console i tried to change the data type to from double to num, still same exception
try {
_emitters.add(emitter);
await handler(event as E, emitter);
} catch (error, stackTrace) {
onError(error, stackTrace);
rethrow;
} finally {
onDone();
}
networkfile.dart
class Repository {
List<FakeStore> collections = [];
Future<List<FakeStore>?> getdata() async {
String url = 'https://fakestoreapi.com/products';
final data = await http.Client().get(Uri.parse(url));
if (data.statusCode != 200) {
return null;
} else {
Iterable values = jsonDecode(data.body);
for (var value in values) {
FakeStore fakeStore = FakeStore.fromJson(value);
collections.add(fakeStore);
}
return collections;
}
}
}
bloc.dart
class FakestoreBloc extends Bloc<FakestoreEvent, FakestoreState> {
final Repository repository;
FakestoreBloc({required this.repository}) : super(FakestoreInitialstate()) {
on<FakestoreEvent>((event, emit) async {
if (event is StorelaodEvent) {
emit(Fakestorelaodingstate());
List<FakeStore>? apiresult = await repository.getdata();
if (apiresult == null) {
emit(FAkestoreErrorstate());
} else {
emit(Fakestoreloadedstate(apiresult: apiresult));
}
}
});
}
}

Flutter custom exception not throwing

I upgraded Flutter from version 2.0.2 to version 2.2.2 and now the custom exceptions that are thrown from a Future function are not being catch.
For example, I got this Future function, where I call another Future that does a server request and returns back the response or throws a custom exception (ApiException) in case of error:
static Future<bool> signUpCustomerRequest(Map<String, dynamic> params) async {
try {
// Here we call this Future function that will do a request to server API.
dynamic _response = await _provider.signUpCustomer(params);
if (_response != null) {
updateUserData(_response);
return true;
}
return false;
} on ApiException catch(ae) {
// This custom exception is not being catch
ae.printDetails();
rethrow;
} catch(e) {
// This catch is working and the print below shows that e is Instance of 'ApiException'
print("ERROR signUpCustomerRequest: $e");
rethrow;
} finally {
}
}
And this is the Future function that does the request to server and throws the ApiException:
Future<User?> signUpCustomer(Map<String, dynamic> params) async {
// POST request to server
var _response = await _requestPOST(
needsAuth: false,
path: routes["signup_client"],
formData: params,
);
// Here we check the response...
var _rc = _response["rc"];
switch(_rc) {
case 0:
if (_response["data"] != null) {
User user = User.fromJson(_response["data"]["user"]);
return user;
}
return null;
default:
print("here default: $_rc");
// And here we have the throw of the custom exception (ApiException)
throw ApiException(getRCMessage(_rc), _rc);
}
}
Before upgrading to Flutter 2.2.2 the catch of custom exceptions worked perfectly. Did something change on this Flutter version? Am I doing something wrong?
Thanks!
I was able to reproduce your bug with the following code:
class ApiException implements Exception {
void printDetails() {
print("ApiException was caught");
}
}
Future<void> doSomething() async {
await Future.delayed(Duration(seconds: 1));
throw ApiException();
}
void main() async {
try {
await doSomething();
} on ApiException catch (ae) {
ae.printDetails();
} catch (e) {
print("Uncaught error: $e"); // This line is printed
}
}
There's an open issue on the dart sdk, which I think might be related, though I'm not sure: https://github.com/dart-lang/sdk/issues/45952.
In any case, I was able to correct the error by returning a Future.error, instead of throwing the error directly:
class ApiException implements Exception {
void printDetails() {
print("ApiException was caught"); // This line is printed
}
}
Future<void> doSomething() async {
await Future.delayed(Duration(seconds: 1));
return Future.error(ApiException());
}
void main() async {
try {
await doSomething();
} on ApiException catch (ae) {
ae.printDetails();
} catch (e) {
print("Uncaught error: $e");
}
}

How to create Custom Annotations in Dart [duplicate]

I'd like to have common try/catch/finally logic in a decorator-like feature that can "wrap" a function or class method. Consider the scenario:
Class MyClass {
void someMethodA() {
doSomeInitialWork();
try {
doSomething();
} catch (err) {
throw err;
} finally {
doSomeCleanUpWork();
}
}
void someMethodB() {
doSomeInitialWork();
try {
doSomethingElse();
} catch (err) {
throw err;
} finally {
doSomeCleanUpWork();
}
}
}
So on and so forth. The unique parts of each method are just the try body. If I have a bunch of methods, some which require the same logic, is there a "nice" way to avoid redundant code?
Ideally it could be syntax like:
#wrapper
void someMethodA() {
doSomething();
}
#wrapper
void someMethodB() {
doSomethingElse();
}
MyClassInstance.someMethodA(); // call it like this and the wrapper takes care of everything
but I know those are annotations in Dart and not applicable here.
UPDATE
Following jamesdlin answer, I am trying to incorporate the anonymous function solution to a futures/async/await scenario:
Future<dynamic> trySomething(Future<dynamic> Function() callback) async {
doSomeInitialWork();
try {
return await callback();
} catch (err) {
throw err;
} finally {
doSomeCleanUpWork();
}
}
class MyClass {
Future<List<String>> someMethodA() async {
return await trySomething(() async {
return await someApiCall();
});
}
}
That seems to work, but it looks kind of messy. I'm not sure if what I'm doing in the async/await example is appropriate.
Anonymous functions in Dart are rather common (unlike Python, where lambda is very restricted).
You therefore could make a helper function that takes the unique part as a callback.
void trySomething(void Function() body) {
doSomeInitialWork();
try {
body();
} catch (err) {
throw err;
} finally {
doSomeCleanUpWork();
}
}
void someMethodA() {
trySomething(() {
doSomething();
});
}
void someMethodB() {
trySomething(() {
doSomethingElse();
});
}
That's basically what test() from package:test (or testWidgets() from Flutter) do.
Update for the case described in the comment: It's not much different if the methods return Futures. For example, if you start with:
Future<List<String>> someMethodA() async {
return await blah();
}
then you could do:
Future<R> trySomethingAsync<R>(Future<R> Function() body) async {
doSomeInitialWork();
try {
return await body();
} catch (err) {
throw err;
} finally {
doSomeCleanUpWork();
}
}
Future<List<String>> someMethodA() {
return trySomethingAsync(() async {
return await blah();
});
}

How to get the value from Future.error inside catchError?

void main() {
foo().catchError((error) {
if (error is Future) {
error.then((value) => print('value = $value'));
}
});
}
Future<void> foo() async {
throw Future.error('FooError');
}
The error is caught inside catchError but I am not able to retrieve the value of Future.error which is FooError in this example.
Well that's Future.error so you'll have to again use catchError on it.
void main() {
foo().catchError((error) {
if (error is Future) {
error.catchError((error) => print(error)); // prints 'FooError'
}
});
}
Future<void> foo() async {
throw Future.error('FooError');
}
You just don't, there is no point in doing so.
You can either throw the error:
void main() {
foo().catchError((error) {
print('error = $error');
});
}
Future<void> foo() async {
throw 'FooError';
}
Or if that is for whatever reason not convinient, you can use Future.error to create a Future that will have an error already:
void main() {
foo().catchError((error) {
print('error = $error');
});
}
Future<void> foo() {
return Future.error('FooError');
}
But actually throwing a Future.error is redundant and not useful.

How can I retry a Future in Dart/Flutter?

I have a method that does some async processing and want it to retry X times. How can I achieve that in Dart/Flutter?
Use this function:
typedef Future<T> FutureGenerator<T>();
Future<T> retry<T>(int retries, FutureGenerator aFuture) async {
try {
return await aFuture();
} catch (e) {
if (retries > 1) {
return retry(retries - 1, aFuture);
}
rethrow;
}
}
And to use it:
main(List<String> arguments) {
retry(2, doSometing);
}
Future doSometing() async {
print("Doing something...");
await Future.delayed(Duration(milliseconds: 500));
return "Something";
}
I added an optional delay to Daniel Oliveira's answer:
typedef Future<T> FutureGenerator<T>();
Future<T> retry<T>(int retries, FutureGenerator aFuture, {Duration delay}) async {
try {
return await aFuture();
} catch (e) {
if (retries > 1) {
if (delay != null) {
await Future.delayed(delay);
}
return retry(retries - 1, aFuture);
}
rethrow;
}
}
You can use it as follows:
retry(2, doSometing, delay: const Duration(seconds: 1));
Retry from Dart Neat is a good API and, unofficially, it's from Google:
https://pub.dev/packages/retry
This is how I implemented it:
Future retry<T>(
{Future<T> Function() function,
int numberOfRetries = 3,
Duration delayToRetry = const Duration(milliseconds: 500),
String message = ''}) async {
int retry = numberOfRetries;
List<Exception> exceptions = [];
while (retry-- > 0) {
try {
return await function();
} catch (e) {
exceptions.add(e);
}
if (message != null) print('$message: retry - ${numberOfRetries - retry}');
await Future.delayed(delayToRetry);
}
AggregatedException exception = AggregatedException(message, exceptions);
throw exception;
}
class AggregatedException implements Exception {
final String message;
AggregatedException(this.message, this.exceptions)
: lastException = exceptions.last,
numberOfExceptions = exceptions.length;
final List<Exception> exceptions;
final Exception lastException;
final int numberOfExceptions;
String toString() {
String result = '';
exceptions.forEach((e) => result += e.toString() + '\\');
return result;
}
}
This is how I use it:
try {
await retry(
function: () async {
_connection = await BluetoothConnection.toAddress(device.address);
},
message: 'Bluetooth Connect');
} catch (e) {
_log.finest('Bluetooth init failed ${e.toString()}');
}