Flutter Shared Preferences acces in other class - flutter

In the following class I have created a ListView of Strings which are stored sing shared preferences. Now I need to access the content of List<String> categoryList in another class. I do not know where to implement a get function to give other classes access to this List.
One Idea was to create a class for the List (But I dont want to mess up everything)
That is my Class with the List View
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class Categories extends StatefulWidget {
#override
_CategoriesState createState() => _CategoriesState();
}
class _CategoriesState extends State<Categories> {
List<String> categoryList = List<String>();
TextEditingController _textFieldController = TextEditingController();
#override
Widget build(BuildContext context) {
_update();
return Scaffold(
appBar: AppBar(
title: Text("Categories"),
),
body: SafeArea(
child: Container(
color: Colors.white,
child: getCategoriesListView(),
),
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
setState(() {
_displayDialog(context);
});
},
),
);
}
ListView getCategoriesListView() {
return ListView.builder(
itemCount: categoryList.length,
itemBuilder: (context, int position) {
return Card(
color: Colors.white,
elevation: 2.0,
child: ListTile(
title: Text(categoryList[position]),
trailing: GestureDetector(
child: Icon(
Icons.delete,
color: Colors.grey,
),
onTap: () {
setState(() {
_delete(context, categoryList[position]);
});
},
),
),
);
});
}
void _add(BuildContext context, String category) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
categoryList.add(category);
prefs.setStringList('Categories', categoryList);
}
void _delete(BuildContext context, String category) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
categoryList.remove(category);
prefs.setStringList('Categories', categoryList);
}
void _update() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
categoryList = prefs.getStringList('Categories');
});
}
void showSnackBar(BuildContext context, String message) async {
final snackBar = SnackBar(content: Text(message));
Scaffold.of(context).showSnackBar((snackBar));
}
_displayDialog(BuildContext context) async {
_textFieldController.clear();
return showDialog(
context: context,
builder: (context) {
return AlertDialog(
title: Text('Add new category'),
content: TextField(
controller: _textFieldController,
),
actions: <Widget>[
FlatButton(
child: Text('ADD'),
onPressed: () {
setState(() {
String name = _textFieldController.text;
_add(context, name);
Navigator.of(context).pop();
});
},
),
FlatButton(
child: Text('CANCEL'),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
});
}
}
Second Class
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class MonthlyOverview extends StatefulWidget {
#override
_MonthlyOverviewState createState() => _MonthlyOverviewState();
}
class _MonthlyOverviewState extends State<MonthlyOverview> {
List<String> _categories = new List<String>();
#override
Widget build(BuildContext context) {
_getCategory().then((value) {
_categories = value;
});
print(_categories);
return Scaffold(
appBar: AppBar(),
body: Container(
color: Colors.white,
),
);
}
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
}
Console output
I/flutter (13417): []

#Frederik, have you tried implementing a get function in your second class and accessing the list? It could be something like this in your second class,
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
Call (depends on where you're calling it but this should give you an idea):
List<String> _categories = new List<String>();
_getCategory().then((value) {
_categories = value;
});
//Your _categories has the value now , use it here.
Full code:
void main() {
runApp(MaterialApp(
home: new MyApp(),
routes: <String, WidgetBuilder>{
"/monthlyOverview" : (BuildContext context)=> new MonthlyOverview(),
//add more routes here
}
));
}
class MyApp extends StatefulWidget {
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Test'),
),
body: Padding(
padding: EdgeInsets.all(20.0),
child: Center(
child: FlatButton(
child: Text('Next', style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),),
onPressed: () async {
List<String> categoryList = ['Item 1', 'Item 2', 'Item 3'];
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList('Categories', categoryList);
Navigator.of(context).pushNamed("/monthlyOverview");
},
)
)
),
);
}
}
class MonthlyOverview extends StatefulWidget {
#override
_MonthlyOverviewState createState() => _MonthlyOverviewState();
}
class _MonthlyOverviewState extends State<MonthlyOverview> {
List<String> _categories = new List<String>();
#override
void initState() {
super.initState();
_getCategory().then((value) {
_categories = value;
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Container(
color: Colors.white,
child: _categories.length > 0 ? Text(_categories[0] + '\n' + _categories[1] + '\n' + _categories[2], style: TextStyle(fontSize: 18.0, fontWeight: FontWeight.bold),) : Text(''),
)
),
);
}
_getCategory() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
List<String> categoryList = prefs.getStringList('Categories');
return categoryList;
}
}
Hope this helps.

Related

setState() not updating UI elements even though the state variable, a Future, is updated?

I have a HomePage screen which has a FutureBuilder List implemented with a Future function as the state variable. I am updating this Future in another dart file by using keys to access the future. The Future gets updated and I'm sure of this as I've seen the print statements, but when I call the setState method, the UI doesn't show the newly added entry.
Here's my HomePage.dart:
class HomePage extends StatefulWidget {
const HomePage({super.key});
#override
State<HomePage> createState() => HomePageState();
}
class HomePageState extends State<HomePage> {
Future<List<Model>> getData() async {
return await DatabaseHelper.instance.getModels();
}
Future? userFuture;
#override
void initState() {
super.initState();
userFuture = getData();
print(userFuture);
}
#override
Widget build(BuildContext context) {
print('Building listview');
return Center(
child: FutureBuilder<List<Model>>(
future: userFuture as Future<List<Model>>,
builder: ((context, AsyncSnapshot<List<Model>> snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.waiting:
return const CircularProgressIndicator();
default:
if (snapshot.data!.isEmpty) {
return Text('No data present');
} else if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data?.length,
itemBuilder: ((context, index) {
return MyCard(
key: ValueKey(snapshot.data![index].id),
snapshot.data![index].id,
snapshot.data![index].title,
snapshot.data![index].purpose);
}),
);
}
return Text('data');
}
}),
),
);
}
}
Here's my other dart file. Under the AddEntryState I'm updating the Future state variable and then right after calling the setState method.
class RootPage extends StatefulWidget {
const RootPage({super.key});
#override
State<RootPage> createState() => RootPageState();
}
class RootPageState extends State<RootPage> {
static final GlobalKey<HomePageState> homepageKey =
GlobalKey<HomePageState>();
int currentPage = 0;
List<Widget>? pages;
#override
void initState() {
super.initState();
pages = [
HomePage(key: homepageKey),
StatsPage(),
];
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('App Title'),
),
body: pages?[currentPage],
floatingActionButton: FloatingActionButton(
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (context) => AddEntry()));
},
child: Icon(Icons.add),
),
bottomNavigationBar: NavigationBar(
destinations: [
NavigationDestination(icon: Icon(Icons.home), label: 'Home'),
NavigationDestination(icon: Icon(Icons.data_usage), label: 'Stats'),
],
onDestinationSelected: (int index) {
setState(() {
currentPage = index;
print(index);
});
},
selectedIndex: currentPage,
),
);
}
}
class AddEntry extends StatefulWidget {
const AddEntry({super.key});
#override
State<AddEntry> createState() => _AddEntryState();
}
class _AddEntryState extends State<AddEntry> {
final GlobalKey<FormState> _key = GlobalKey<FormState>();
Map<String, String?> formField = <String, String?>{};
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('New Entry'),
),
body: Form(
key: _key,
child: Column(
children: [
Flexible(
child: MyTextField('Title', callback),
),
Flexible(
child: MyTextField('Purpose', callback),
),
Flexible(
child: MyTextField('Password', callback, obscure: true),
),
TextButton(
onPressed: () async {
if (_key.currentState!.validate()) {
_key.currentState?.save();
formField.forEach((label, value) => print('$label = $value'));
await DatabaseHelper.instance.insertModel(Model(
id: null,
title: formField['Title'],
purpose: formField['Purpose'],
lastAccess: DateTime.now().toString(),
dateAdded: DateTime.now().toString(),
password: formField['Password']));
print(await DatabaseHelper.instance.getModels());
// await DatabaseHelper.instance.deleteAllData();
// print(await DatabaseHelper.instance.getModels());
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text('Data Saved!'),
action: SnackBarAction(
label: 'Edit',
onPressed: () {
print('edit pressed!');
},
),
),
);
Navigator.pop(context);
print("HomePage userFuture: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
print("getData function: ");
print(RootPageState.homepageKey.currentState!
.getData()
.then((result) => print(result)));
print("New Future: ");
print(RootPageState.homepageKey.currentState!.userFuture!
.then((result) => print(result)));
setState(() {
RootPageState.homepageKey.currentState!.userFuture =
RootPageState.homepageKey.currentState!.getData();
});
//add logic to rebuild home screen after every addition of entry
}
},
child: Text('Submit'),
),
],
),
),
);
}
callback(varLabel, varValue) {
formField[varLabel] = varValue;
}
}

How to navigate to a new page from search results

I am trying to find out about search navigation and could not find any suitable tutorial showing me how to navigate to specific pages after your search. I hope someone could explain me how I can do this.
After searching "Google" I would like to press on it and be redirected to a new page through navigation.
import 'package:flutter/material.dart';
class SearchPage extends StatefulWidget {
#override
_SearchPageState createState() => _SearchPageState();
}
class _SearchPageState extends State<SearchPage> {
Widget appBarTitle = Text(
"Search",
style: TextStyle(color: Colors.white),
);
Icon actionIcon = Icon(
Icons.search,
color: Colors.white,
);
final key = GlobalKey<ScaffoldState>();
final TextEditingController _searchQuery = TextEditingController();
List<String> _list;
bool _isSearching;
String _searchText = "";
_SearchPageState() {
_searchQuery.addListener(() {
if (_searchQuery.text.isEmpty) {
setState(() {
_isSearching = false;
_searchText = "";
});
} else {
setState(() {
_isSearching = true;
_searchText = _searchQuery.text;
});
}
});
}
#override
void initState() {
super.initState();
_isSearching = false;
initData();
}
void initData() {
_list = List();
_list.add("google");
_list.add("IOS");
_list.add("Android");
_list.add("Linux");
_list.add("MacOS");
_list.add("Windows");
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: key,
appBar: buildBar(context),
body: new ListView(
padding: new EdgeInsets.symmetric(vertical: 8.0),
children: _isSearching ? _buildSearchList() : _buildList(),
),
);
}
List<ChildItem> _buildList() {
return _list.map((contact) => new ChildItem(contact)).toList();
}
List<ChildItem> _buildSearchList() {
if (_searchText.isEmpty) {
return _list.map((contact) => new ChildItem(contact))
.toList();
}
else {
List<String> _searchList = List();
for (int i = 0; i < _list.length; i++) {
String name = _list.elementAt(i);
if (name.toLowerCase().contains(_searchText.toLowerCase())) {
_searchList.add(name);
}
}
return _searchList.map((contact) => new ChildItem(contact))
.toList();
}
}
Widget buildBar(BuildContext context) {
return new AppBar(
centerTitle: true,
title: appBarTitle,
actions: <Widget>[
new IconButton(icon: actionIcon, onPressed: () {
setState(() {
if (this.actionIcon.icon == Icons.search) {
this.actionIcon = new Icon(Icons.close, color: Colors.white,);
this.appBarTitle = new TextField(
controller: _searchQuery,
style: new TextStyle(
color: Colors.white,
),
decoration: new InputDecoration(
prefixIcon: new Icon(Icons.search, color: Colors.white),
hintText: "search...",
hintStyle: new TextStyle(color: Colors.white)
),
);
_handleSearchStart();
}
else {
_handleSearchEnd();
}
});
},),
]
);
}
void _handleSearchStart() {
setState(() {
_isSearching = true;
});
}
void _handleSearchEnd() {
setState(() {
this.actionIcon = new Icon(Icons.search, color: Colors.white,);
this.appBarTitle =
new Text("search", style: new TextStyle(color: Colors.white),);
_isSearching = false;
_searchQuery.clear();
});
}
}
class ChildItem extends StatelessWidget {
final String name;
ChildItem(this.name);
#override
Widget build(BuildContext context) {
return new ListTile(title: new Text(this.name));
}
}
You can also do it with a SearchDelegate.
Query and navigation under the buildSuggestions.
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
The important part is pairing yourList's index with suggestionList index :
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index])))
Below is all the code with navigation.
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: HomePage(),
);
}
}
class HomePage extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Search Example"),
actions: [
IconButton(
icon: Icon(Icons.search),
onPressed: () {
showSearch(context: context, delegate: SearchItem());
}),
],
),
);
}
}
final List<String> myList = [
"google",
"IOS",
"Android",
"Linux",
"MacOS",
"Windows"
];
class SearchItem extends SearchDelegate<String> {
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () {
query = "";
})
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: AnimatedIcon(
icon: AnimatedIcons.menu_arrow,
progress: transitionAnimation,
),
onPressed: () {
close(context, null);
});
}
#override
Widget buildResults(BuildContext context) {}
#override
Widget buildSuggestions(BuildContext context) {
final suggestionsList = query.isEmpty
? myList
: myList
.where((p) => p.toLowerCase().contains(query.toLowerCase()))
.toList();
return ListView.builder(
itemBuilder: (context, index) => ListTile(
onTap: () {
close(context, suggestionsList[index]);
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DetailScreen(myList
.indexWhere((item) => item == suggestionsList[index]))));
},
title: Text(suggestionsList[index]),
),
itemCount: suggestionsList.length,
);
}
}
class DetailScreen extends StatelessWidget {
final int index;
DetailScreen(this.index);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("${myList[index]}"),),
body: Center(
child: Text(
"${myList[index]}",style: TextStyle(fontSize: 22),
),
));
}
}

Flutter how to pass array and show in other widget

I have a list of arrays i need to pass it to the other stateful widget and show the array there
This is my function code which retrieve data from API
Future<List> doSomeAsyncStuff() async {
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'Cnic');
print(value);
String url = 'http://api.php?offset=0&limit=1&cnic=${value}' ;
final msg = jsonEncode({"cnic": value});
Map<String,String> headers = {'Content-Type':'application/json'};
String token = value;
final response = await http.get(url);
var Data = json.decode(response.body);
print(Data);
var familyMembers = Data["records"][0]["family_members"];
print(familyMembers);
for (var familyMember in familyMembers){ //prints the name of each family member
print(familyMember["name"]);
print(familyMember["gender"]);
}
}
As you can see there is 2 list familyMember["name"] and familyMember["gender"] i need to pass it to statefulwidget
I am simple passing it like this
Navigator.push(
context,
MaterialPageRoute(builder: (context) => PersonalPage(familyMember["name"], familyMember["gender"])),
);
This is my other stateful widget I need to show the array of name and gender here
import 'package:flutter/material.dart';
class PersonalPage extends StatefulWidget {
final String name;
final String gender;
PersonalPage(this.name, this.gender);
#override
_PersonalPageState createState() => _PersonalPageState();
}
class _PersonalPageState extends State<PersonalPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('I need to print name and gender here ')
),
);
}
}
flut
Try this and change your code as per this: As your First Page code is missing I have created a dummy forst Page.
import 'package:flutter/material.dart';
void main() {
runApp(MaterialApp(
title: 'My APP',
home: FirstRoute(),
));
}
class FirstRoute extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('List of ....'),
),
body: Center(
child: RaisedButton(
child: Text('Open details'),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => PersonalPage("NAME","GENDER")),
);
},
),
),
);
}
}
class PersonalPage extends StatefulWidget {
final String name;
final String gender;
PersonalPage(this.name, this.gender);
#override
_PersonalPageState createState() => _PersonalPageState();
}
class _PersonalPageState extends State<PersonalPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Row(
children : [
Text(widget.name),
Text(widget.gender),
]
)
),
);
}
}
You are doing wrong you are passing list and in stateful widget you mention its a string you can do something like this
List<String> familyMemberName = [];
List<String> familyMemberGender = [];
Future<List> doSomeAsyncStuff() async {
final storage = new FlutterSecureStorage();
String value = await storage.read(key: 'Cnic');
print(value);
String url = 'http://api.php' ;
final msg = jsonEncode({"cnic": value});
Map<String,String> headers = {'Content-Type':'application/json'};
String token = value;
final response = await http.get(url);
var Data = json.decode(response.body);
print(Data);
var familyMembers = Data["records"][0]["family_members"];
print(familyMembers);
for (var familyMember in familyMembers){
familyMemberName.add(familyMember["name"]);
familyMemberGender.add(familyMember["gender"]);
print(familyMemberName);
}
}
and in you personal widget like this
import "package:flutter/material.dart";
class PersonalPage extends StatefulWidget {
final List<String> names;
final List<String> relation;
PersonalPage(this.names,this.relation);
#override
_PersonalPageState createState() => _PersonalPageState();
}
class _PersonalPageState extends State<PersonalPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body:
ListView.builder( //use ListView here to show all the names and genders
itemCount: widget.names.length,
itemBuilder: (BuildContext context,int index){
return Padding(
padding: EdgeInsets.only(left: 10, right: 10, bottom: 10, top: 10),
child: Card(
child: Padding(
padding: EdgeInsets.all(5),
child: Column(
children: <Widget>[
Row(
children: <Widget>[
Text('Name:', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),),
Text(widget.names[index])
],
),
Row(
children: <Widget>[
Text('Gender:', style: TextStyle(color: Colors.blue, fontWeight: FontWeight.bold),),
Text(widget.genders[index])
],
),
],
),
),
),
);
})
);
}
}
Sorry i test code so thats why i add it in card
Text(widget.name)
Text(widget.gender)
or
Text("My name is ${widget.name} and my gender is ${widget.gender}")

How to save the searched item from search bar and display the saved list from sharedprefernce in flutter

I a trying to save the searched item from searchbar to sharedpreference and want to display the list of searched list in other page but unable to achieve it. Below is my code how I am saving and retrieving it from the sharedprefernce.
I have updated my code please go through it.
Update
I have query which I am passing it to the url and getting the list directly
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
List<Ayurwikilist> ayurwikilist = [];
#override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text('Ayurwiki'),
actions: <Widget>[
new IconButton(
icon: new Icon(Icons.search),
onPressed: () {
showSearch(
context: context,
delegate: CustomSearchDelegate(ayurwikilist));
},
),
],
),
body: _body(),
);
}
class CustomSearchDelegate extends SearchDelegate {
List<Ayurwikilist> ayurwikilist = [];
CustomSearchDelegate(this.ayurwikilist);
Future<Ayurwikilist> fetchPost() async {
final response = await http.get(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
print(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
return Ayurwikilist.fromJson(json.decode(response.body));
}
#override
ThemeData appBarTheme(BuildContext context) {
assert(context != null);
final ThemeData theme = Theme.of(context);
assert(theme != null);
return theme;
}
#override
List<Widget> buildActions(BuildContext context) {
return [
IconButton(
icon: Icon(Icons.clear),
onPressed: () async{
query = '';
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setString('name', "$query");
print(query);
},
),
];
}
#override
Widget buildLeading(BuildContext context) {
return IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
close(context, null);
},
);
}
#override
Widget buildResults(BuildContext context) {
return Container();
}
#override
Widget buildSuggestions(BuildContext context) {
return FutureBuilder<Ayurwikilist>(
future: fetchPost(),
builder: (BuildContext context, AsyncSnapshot snapshot) {
if (snapshot.hasData) {
print(snapshot.data.toString());
return ListView.builder(
itemCount: snapshot.data.query.search.length,
itemBuilder: (BuildContext context, int index) {
var title = snapshot.data.query.search[index].title;
return GestureDetector(
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => Detailpage(
snapshot.data.query.search[index].title,
// 'images/ayurwiki.png'
),
));
},
child: ListTile(
title: Text(title),
),
);
});
} else {
return Center(
child: Text(
'Search in ayurwiki',
style: TextStyle(color: Colors.grey, fontSize: 18),
),
);
}
},
);
}
}
class _HistoryState extends State<History> {
var myName;
getCredential() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var query = prefs.getString('query');
setState(() {
myName = query;
});
print('item : $query');
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title:Text('Rcently viewed item'),
),
body: Container(
decoration: new BoxDecoration(color: Colors.white),
child: myName == null ? Text('No items') : Text('$myName'),
),
);
}
}
Update
Future<Ayurwikilist> fetchPost() async {
final response = await http.get(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
print(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
SharedPreferences prefs = await SharedPreferences.getInstance();
prefs.setStringList('name', query as List);
return Ayurwikilist.fromJson(json.decode(response.body));
}
getCredential() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var name = prefs.getStringList('name');
setState(() {
myName = name;
});
print('item : $name');
}
you should call getCredential() function in initState
class _HistoryState extends State<History> {
var myName;
initState(){
super.initState();
getCredential();
}
getCredential() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var query = prefs.getString('query');
setState(() {
myName = query;
});
print('item : $query');
}
#override
Widget build(BuildContext context) {
return new Scaffold(
appBar: new AppBar(
title:Text('Rcently viewed item'),
),
body: Container(
decoration: new BoxDecoration(color: Colors.white),
child: myName == null ? Text('No items') : Text('$myName'),
),
);
}
}
update:
Future<Ayurwikilist> fetchPost() async {
query = 'something you need';
final response = await http.get(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
print(
'https://www.example.org/api.php?action=query&list=search&srsearch=$query&utf8=&format=json');
prefs.setString('name', query);
return Ayurwikilist.fromJson(json.decode(response.body));
}

Can't get data from api

While I am passing value from home page in API page after applying logic how I am not getting data in my result variable. What I am doing wrong?
Here is my home page where I passes the value -
import 'package:flutter/material.dart';
import 'sourceScreen.dart';
import 'models/API.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value=0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =1;
API(value: value);
});
},
child:Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =0;
API(value: value);
});
},
child:Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
Here is my API page where I wanna use that value with some logic which is given below hope u will understand-
import 'model.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
class API{
int value;
API({this.value});
Future<List<Source>> fetchNewsSource() async {
final world ='https://newsapi.org/v2/sources?apiKey=';
final india = 'https://newsapi.org/v2/sources?language=en&country=in&apiKey=';
String result;
void logic(){
if(value==1){
result = india;
}
else if(value==0){
result = world;
}
}
final response = await http.get(result);
if (response.statusCode == 200) {
List sources = json.decode(response.body)['sources'];
return sources.map((source) => new Source.formJson(source)).toList();
} else {
throw Exception('Fail to load data');
}
}
}
Here is home page -
import 'package:flutter/material.dart';
import 'sourceScreen.dart';
import 'models/API.dart';
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value=0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title:Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =1;
API(value: value);
});
},
child:Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: (){
Navigator.push(context, MaterialPageRoute(builder: (context)=>SourceScreen({})));
setState(() {
value =0;
API(value: value);
});
},
child:Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
Source screen
import 'package:flutter/material.dart';
import 'models/model.dart';
import 'models/card.dart';
import 'article.dart';
import 'models/API.dart';
class SourceScreen extends StatefulWidget {
SourceScreen(Map<int, int> map);
#override
_SourceScreenState createState() => _SourceScreenState();
}
class _SourceScreenState extends State<SourceScreen> {
var list_source;
var refreshKey = GlobalKey<RefreshIndicatorState>();
#override
void initState() {
super.initState();
refreshListSource();
}
Future<Null> refreshListSource() async {
API api = new API();
refreshKey.currentState?.show(atTop: false);
setState(() {
list_source = api.fetchNewsSource();
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
appBar: AppBar(
elevation: 1.0,
backgroundColor: Color.fromRGBO(58, 66, 86, 1.0),
title: Text('uTTerNews'),
),
body: Center(
child: RefreshIndicator(
child: FutureBuilder<List<Source>>(
future: list_source,
builder: (context, snapshot) {
if (snapshot.hasError) {
Text('Error: ${snapshot.error}');
} else if (snapshot.hasData) {
List<Source> sources = snapshot.data;
return new ListView(
children: sources
.map((source) =>
GestureDetector(
onTap: () {
Navigator.push(context, MaterialPageRoute(
builder: (context) =>
articleScreen(source: source,)));
},
child: card(source),
))
.toList());
}
return CircularProgressIndicator();
},
),
onRefresh: refreshListSource),
),
),
);
}
}
Output:
Try this full code:
void main() => runApp(MaterialApp(home: Home()));
class Home extends StatefulWidget {
#override
_HomeState createState() => _HomeState();
}
class _HomeState extends State<Home> {
int value = 0;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("uTTerNews")),
body: Center(
child: Column(
children: <Widget>[
FlatButton(
onPressed: () async {
value = 1;
List list = await API(value: value).fetchNewsSource();
Navigator.push(context, MaterialPageRoute(builder: (context) => SourceScreen(list)));
},
child: Text('India'),
color: Colors.blue,
),
FlatButton(
onPressed: () async {
value = 0;
List list = await API(value: value).fetchNewsSource();
Navigator.push(context, MaterialPageRoute(builder: (context) => SourceScreen(list)));
},
child: Text('World'),
color: Colors.blue,
),
],
),
),
);
}
}
class API {
int value;
API({#required this.value});
Future<List<dynamic>> fetchNewsSource() async {
final world = 'https://newsapi.org/v2/sources?apiKey=$apiKey';
final india = 'https://newsapi.org/v2/sources?language=en&country=in&apiKey=$apiKey';
String result;
if (value == 1)
result = india;
else if (value == 0) result = world;
final response = await http.get(result);
if (response.statusCode == 200) {
List sources = json.decode(response.body)['sources'];
return sources;
} else {
throw Exception('Fail to load data');
}
}
}
class SourceScreen extends StatefulWidget {
final List list;
SourceScreen(this.list);
#override
_SourceScreenState createState() => _SourceScreenState();
}
class _SourceScreenState extends State<SourceScreen> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text("Channels")),
body: ListView(
children: widget.list.map((map) => ListTile(title: Text(map["name"]))).toList(),
),
);
}
}