Need to apply localisation for the API data in flutter - flutter

I'm working on flutter application that one should support localisation for multiple languages. I used to create .arb file for the localisation but for the API data i couldn't apply arb files ?

Here two ways make localization.
Use ARB (Application Resource Bundle) files
manage from API
manage from Api
make API post method they past language code. they return all arb file data from the backend side.
and then store data in the local database and display all places you want display.

in Get Package you can extend the translations class and assign that class object to GetMaterialApp translations property,
You just need to get your Language Map files from API and pass to overrided keys function. For more please check doc https://pub.dev/packages/get#translations
API Response like
res= {
'en': {
'SEARCH_FOR_SERVICES_AND_PROFESSIONALS':
'Search for services and professionals',
'MEMBERSHIP': 'Membership',
'PURCHASE': 'Purchase',
'GET_STARTED': 'Get started',
}
}
GetMaterialApp(
title: Constants.appName,
translations: Localization(res), //Localization class
and localization class
class Localization extends Translations {
// final Map<String, Map<String, String>>? res;
// Localization(this.res);
#override
Map<String, Map<String, String>> get keys => res

Related

How to add new data into Future<dynamic> in dart / flutter?

I am developing a chat system in mobile application using Flutter / Dart.
I have fetched a user's message records from server by API and received result as Future<dynamic>. This result has list of chat data. If I pass it to FutureBuilder widget. It works and lists chat records in listTile. Everything is working well.
When user adds a new chat message then I post the that text message to server by API to store into database. It works and response status is 200 which means message has been added on server's database.
I have instance of newly added chat message, I want to append / add it to previously fetched Future<dynamic> result.
Kindly suggest me how can I do this? Can we update Future<dynamic> typed data? Thanks.
Future can emit only one item by design. If you want to emit multiple items, use Stream: https://api.flutter.dev/flutter/dart-async/Stream-class.html
To get to know how to generate streams have a look on this: https://dart.dev/articles/libraries/creating-streams
Most likely what you want to do is use rxdart's BehaviorSubject or dart's StreamController (they share api, so just substitute the name, except for ValueStream, which is specific to rxdart, this one will have to be replaced with just Stream):
class Api {
final _subject = BehaviorSubject<DataToDisplay>();
ValueStream<DataToDisplay> get data => _subject.stream;
void fetchData() {
final data = downloadDataFromSomewhere();
_subject.add(data);
}
}
Then just create a StreamBuilder similarly to FutureBuilder.

Is there a way I can translate my flutter app for free?

I am making a flutter app that fetches data from a database using an API. The client wants me to add multilanguage support, so is there a way with which I can change the language of the whole app. Also the data that is being fetched from database needs to be translated. So it would be better if the data is translated before being displayed.
Thank you.
The best approach would be to get translated data from the backend as it will be a lot faster compared to translating the text at the mobile end.
There is this translator package which you can use to convert the data fetched from the backend.
However, note that your app will become slow when you implement this because you will have to wait for two API calls:
For fetching data from the backend
Uploading this fetched data & then getting translations back
The translator package makes use of Google Translator to translate text into any language that you want.
void main() async {
final translator = GoogleTranslator();
final input = "Здравствуйте. Ты в порядке?";
translator.translate(input, from: 'ru', to: 'en').then(print);
// prints Hello. Are you okay?
var translation = await translator.translate("Dart is very cool!", to: 'pl');
print(translation);
// prints Dart jest bardzo fajny!
print(await "example".translate(to: 'pt'));
// prints exemplo
}
The simple use case example mentioned in the package.

Flutter/Retrofit: How to call API with multiple sort order in query param using Retrofit in Flutter?

I am using Retrofit API calls in my flutter app. So far everything going good until the multiple sorting keys have been added to API so that the final URL looks like as below:
https://example.com/contents?page=0&size=20&sort=startTime,desc&sort=id,desc
My current code with just single sort as shown below:
#GET('contents')
Future<HttpResponse<ContentList>> getContents(
#Query("page") int page,
#Query("size") int size,
#Query("sort") String sort,
#Query("desc") String desc,
);
it would be
#Query("sort[]") List<String> sorts
use #Queries()
example
#GET('/demo')
Future<String> queries(#Queries() Map<String, dynamic> queries);

Flutter - Storing Authenticated User details

I am new to Flutter and I am writing an app which requires users to login. I already have an API that provides me with a JWT. I then store this using the secure storage library.
Once the user gets the 200 OK with the token, I want to send another request to the server to retrieve the user's details and store it in a kind of singleton class, so I can use it through out the app until he logs out. There are so many buzzwords being thrown at me right now, Providers and BLoCs.
I was wondering what is the best practice to store the current logged in user details in the app? Previously I've been aware of storing the data in a singleton class. But now I'm not sure whether I should write a singleton class or a Provider? (I'm still rusty on my knowledge about how Providers and BLoCs work).
Start Simple
A simple starting point to store the data, which i assume is the form of key/value pairs, would be using shared preferences.
What are Shared Preferences
The main use of Shared Preferences is to save user preferences, settings, maybe data (if not too large) so that next time the application is launched, these pieces of information could be retrieved and used.
How to use
Set an instance variable of Shared Preferences and store the value with a key identifier.
Any time you want to retrieve the value when the app starts, just get it using the key. See example below of setting and getting a stored username.
Future<bool> setUserName(String value) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.setString("username",value);
}
Future<String> getUserName(String value) async {
final SharedPreferences prefs = await SharedPreferences.getInstance();
return prefs.getString("username");
}
Installation
To installed shared preferences, add this to your package's pubspec.yaml file:
dependencies:
shared_preferences: ^0.5.7+3
More information on the package page.
Solution 1
This is how my app stores data:
Create a new dart file for storing "global" variables like so, and store all the "session" data there:
class SessionData{
String encryptedUserId;
String encryptedPassword;
String encryptedToken;
int userId;
}
SessionData globalSessionData;
//Having a clear function is pretty handy
void clearSessionData(){
globalSessionData = new SessionData();
}
And if you named the file for example global.dart import it, read and write nonpermanent data to it (persist until the app is closed):
import 'global.dart' as global;
global.globalSessionData = ...;
//If you want to clear it:
global.clearSessionData();
Solution 2
If you want to persist the data even if the application closes there are two ways to do that:
Solution 2a
Use sharedPrefences to store and retrieve key-data values on the user's device:
import 'package:shared_preferences/shared_preferences.dart';
final SharedPreferences prefs = await SharedPreferences.getInstance();
//Write different types of data
await prefs.setBool("male", true);
await prefs.setDouble("key", 7.0);
await prefs.setString("username", "Mr. User");
//Retrive different types of data
prefs.getBool("male");
prefs.getDouble("key");
prefs.getString("username");
Solution 2b
Use sqflite to store advanced data structures, as it is a fully-featured database.
Flutter has a great tutorial on using SQLite with flutter. Although if you go with this type of solution you must know a little SQL.

Flutter - Dependency Injection

I am after some best practise tips for developing my Flutter app.
Currently, I have an app with multiple pages and multiple plugins such as network connection, SQLite, Location etc.
Currently, on each page, I am creating a new instance of each plugin I need access to as shown below, and then using the plugin functionality.
final _secureStorage = FlutterSecureStorage();
final FirebaseMessaging _firebaseMessaging = FirebaseMessaging();
What I want to achieve: I would like to possibly only create an instance of these classes once, and then be able to access the instance in all pages - something like Dependency Injection.
Currently, I am looking into InheritedWidget widget or the Provider package, however, I am not sure if they do what I am trying to achieve as I don't want to inherit or pass around widgets, I want to inject classes instances.
You could try out, the get_it package, since it is not tied to Flutter.
https://pub.dev/packages/get_it
The ioc_container may suit your case because it has specific documentation on how to use it with Firebase and firebase Messaging. It does exactly as you say: initialize Firebase asynchronously and store the instances as singletons with dependency injection.
Here is a snippet of the code from the documentation:
extension FlutterFireExtensions on IocContainerBuilder {
void addFirebase() {
//These factories are all async because we need to ensure that Firebase is initialized
addSingletonAsync(
(container) {
WidgetsFlutterBinding.ensureInitialized();
return Firebase.initializeApp(
options: container.get<FirebaseOptions>(),
);
},
);
addSingletonAsync(
(container) async => FirebaseAuth.instanceFor(
app: await container.getAsync<FirebaseApp>(),
),
);
addSingletonAsync(
(container) async => FirebaseFirestore.instanceFor(
app: await container.getAsync<FirebaseApp>(),
),
);
addSingletonAsync((container) async {
//Ensure we have already initialized Firebase
await container.getAsync<FirebaseApp>();
return FirebaseMessaging.instance;
});
}
}