im a very newbie to flutter integration testing. For now I only know how to write basic sheets of finding elements on a screen and make some actions to them.
Can please anyone help me on how to pass a variable in a function if i want to reuse it? Example:
static Future<void> createProjectFromWizard(FlutterDriver driver, String projectName, bool direct) async {
final faker = new Faker();
final buttonStart = find.byValueKey(OnboardingIds.buttonStart);
await driver.waitFor(buttonStart).then((_) => driver.tap(buttonStart));
I want to reuse this function but instead of final buttonStart I need to find another ui-button. How can I do this without re-writing this function? (Because it is a very long one, i pasted a short piece)
Related
I have this project, so I already stored the data I need in flutter storage but I'm unable to pick that data and use it in my text widget
checkname() async {
String? name = await storage.read(key: "name");
setState(() {
splitname = name;
});
print(splitname);
}
checkname();
I created this function to read the value in the storage but but it kept on printing the value about a 1000 times a minutes and I feel something might go wrong, is there a way I could go around it.
Printing the value about a 1000 times indicates that you are calling the function inside build method.
Here's on overall of what you should do:
create a statuful widget
call checkname inside initState function of the widget
I am using flutter_typeahead for showing place suggestions to users as they search using a text field and fetching these suggestions from HERE Maps. flutter typeahead package has an asynchronous callback function that requires, a list of strings to be returned that would then be shown to the user. The problem is that HERE Map's search engine doesn't return the search results and instead takes its own callback function which is called with the suggestions. Here's an example of it to make it clear.
TypeAheadFormField(
suggestionsCallback: (pattern) async {
final taskHandle = _searchEngine.suggest(
TextQuery.withAreaCenter(pattern, centerCoords),
searchOptions,
(error, suggestions) {
// How can i return these suggestions back from the suggestionsCallback?
final suggestionStrings = _handleSuggestions(error, suggestions);
},
);
},
),
The taskHandle also doesn't provide any way to await the searchEngine so I basically have no way of knowing when the suggestions will be available to return them by using a global variable (storing the suggestions after the searchEngine completes its callback and then returning the stored suggestions from the suggestionCallback.
The HERE SDK notifies in the SuggestionCallback when suggestions are available. Inside the callback you can proceed with your app logic, and, e.g. call typeAhead:
_searchEngine.suggest(
TextQuery.withAreaCenter(
"piz", // User typed "piz".
centerGeoCoordinates),
searchOptions, (SearchError? searchError, List<Suggestion>? list) async {
// Suggestions have been provided by HERE SDK. Use the results ...
});
Instead of using global variables it's probably better to proceed inside the callback. However, if you want to make this call blocking, you can wrap it in an async method that returns a Future. When calling this method you can await the resuts.
I'm using Flutter hooks to fetch data by combining useMemorized and useFuture like this:
final _latestDocsFuture =
useMemoized(() => getLatestDocs());
final _latesetDocsSnapshot = useFuture(_latestDocsFuture);
The problem with this hook is I can't re-trigger the useFuture to re-fetch the data in case of an error (allowing the user to tap on a button to try and fetch the data again).
Is there any method that can let me re-trigger the useFuture hook?
The useMemoized hook accepts a list of keys that can be used to create new instances of the Future, which would cause useFuture to run again.
I'd suggest using the UniqueKey class to achieve this
final reloadKey = useState(UniqueKey());
final latestDocsFuture = useMemoized(() => getLatestDocs(), [reloadKey.value],);
final latestDocsSnapshot = useFuture(latestDocsFuture);
Then whenever you wish to reload, you can update the value of reloadKey
reloadKey.value = UniqueKey();
We have a Features class that we are trying to fill when a screen loads. Its an http call that returns the object. Im struggling with how to do this. All of our http calls are done on a button click:
here is the call
Future<Features> getFeatureStatus(String userID) async {
Features _features;
final response =
await http.post('http://url/api/Features',
headers: {"Content-Type": "application/json",
'Accept': 'application/json',},
body: json.encode({'userID' : userID }));
_features = Features.fromJson(json.decode(response.body));
return _features;
}
When i try to call it at the top of the class I get errors and cant get to the values.
class FlutterReduxApp extends StatelessWidget {
static final User user;
static final Features features = getFeatureStatus(user.userId);
The error I get is -- "A value of type 'Future' can't be assigned to a variable of type 'Features'.
Try changing the type of the variable, or casting the right-hand type to 'Features'.dart(invalid_assignment)"
Im sure im doing something incorrect here but I havent done a screen load call yet.
The getFeatureStatus function is returning a Future<Features> while you're trying to read it as type Features in the stateless widget.
There are different ways to read the value but since you have a button, you could convert the widget into a StatefulWidget then use the onPressed function to read the value and update the state afterwards such as.
onPressed: () async {
features = await getFeatureStatus(user.userId);
setState((){
// do something
});
}
In this case, the value features cannot be a static final so you'll have to change it to Features features.
Edit based on comment:
You could also do this inside an initState:
Features features;
#override
void initState () {
super.initState();
_asyncMethod();
}
_asyncMethod() async {
features = await getFeatureStatus(user.userId);
setState((){});
}
so in the widget build method you could do:
return (features == null)
? CircularProgressIndicator()
: MyWidget(...); // where features is used.
getFeatureStatus(user.userId).than((features)
{
// you will get the features object
//you can work on that object
}
);
calling the getFeaturesStatus method in the initState() when using the statefull.
First thing first, this line static final Features features = getFeatureStatus(user.userId); will not work as you are trying to assign a type Future to the type Features.
The solution for this is to await the future so that it resolves and returns a Feature data type that satisfies your variable named 'features'.
This goes as follows: static final Features features = await getFeatureStatus(user.userId); but this has to be in a separate function which is explicitly defined with the async parameter.
This solves the error in the respect of code that you have written, but as you stated that you want this to load after the screen loads (Or technically, when the main widget is "mounted").
The solution for this logical aspect can be the use of this.mounted.
All widgets have a bool this.mounted property. It turns true when the buildContext is assigned.
In short, suppose you want to run a function after any widget is mounted/loaded, you can test it via
if(this.mounted){
//Whatever you want to do when the widget has been mounted...
}
Don't understand all those explanations on the internet about SHARED PREFERENCES in Flutter and I am a little (little is not true) frustrated after searching and trying for three days. So I am calling out here for my hero.
I am working at my first app in Flutter. It is for calculate volume in weight users need for their project.
I have 4 screens, actived by a bottom-bar. 1 Screen is the Setting screen, where users can put their (1)mixing ratio, (2)the weight of the liquid and (3) the Boolean if they are measuring on weight(gr) of volume (ml). If they are using volume, option 2 is not necessary is then hidden.
I want them to fill that as their settings. These settings I need for the formula on one of the other pages. If they fill in nothing, I have default values. I don't want that they have to fill in these settings every time but just once. Or twice if they use another kind of liquid. :-)
I have tried the SQFLITE package but I think the package SHARED PREFERENCES is what I need. I have watched all those video's on YouTube, I have googled and read and tried a lot of items, but I still don't get it what if have to do and where I have put the code. It always seems that if I retype what the experts are typing that I am the only one who get failure.
YES, I AM A BEGINNER (You all were once) and I am struggling with this topic now.
My questions to you:
1. Is the package SHARED PREFERENCES the best solution for my app?
2. Where do I put the setting for writing the database.
3. How do I place a default value for the first time in this database.
4. Is it possible to set a value on the Setting screen, and get the value on another page, without using the Navigation (because I use a bottom-bar).
When you read to the end: THANK YOU!
import 'package:flutter/material.dart';
import 'constants.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'dart:async';
class SettingsPage extends StatefulWidget {
#override
SettingsPageState createState() => SettingsPageState();
}
class SettingsPageState extends State<SettingsPage> {
int mixingRatio = 50;
int liquidGravity = 115;
bool weight = true;
#override
void initState() {
super.initState();
}
Future<int> _getIntFromSharedPref() async {
final prefs = await SharedPreferences.getInstance();
final mixingRatio = prefs.getInt('mixingRatio');
if (mixingRatio == null) {
return 50;
}
return mixingRatio;
}
Future<void> _resetMixingRatio() async {
final prefs = await SharedPreferences.getInstance();
await prefs.setInt('mixingRatio', 50);
}
-----------------
onPressed: () {
setState(
() {
weight = true;
weightOrVolume = 'GR';
},
);
},
Answering your questions.
Is the package SHARED PREFERENCES the best solution for my app?
For saving settings, surely this is the best package.
Where do I put the setting for writing the database.
You can save the settings anywhere using SharedPreference instance like:
sharedPrefs.putInt("key", 10);
How do I place a default value for the first time in this database
You can get it using dart syntax ??
int savedValue = sharedPrefs.getInt("key") ?? 0; // default value will be 0
Is it possible to set a value on the Setting screen, and get the value on another page, without using the Navigation.
Yes, you can do it, by either making global variable or retrieving it using getInt on the current screen.