A non-null String must be provided to a Text widget. 'package:flutter/src/widgets/text.dart': Failed assertion: line 360 pos 10: 'data != null' - android

Flutter Error : A non-null String must be provided to a Text widget. 'package:flutter/src/widgets/text.dart': Failed assertion: line 360 pos 10: 'data != null'
Another exception was thrown: A non-null String must be provided to a Text widget.
This is Main.dart
import 'package:bheekho_foundation/widgets/app.dart';
import 'package:flutter/material.dart';
void main() {
runApp(App());
}
This is App.dart
import 'package:bheekho_foundation/screens/home.dart';
import 'package:flutter/material.dart';
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: HomeScreen(),
);
}
}
This is Home.dart
import 'dart:convert';
import 'package:bheekho_foundation/models/request.dart';
import 'package:bheekho_foundation/services/request_service.dart';
import 'package:flutter/material.dart';
class HomeScreen extends StatefulWidget {
#override
_HomeScreenState createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
RequestService _requestService = RequestService();
// ignore: unused_element
Future<List<Request>> _getAllRequest() async {
var result = await _requestService.getAllRequests();
List<Request> _list = List<Request>();
if (result != null) {
var requests = json.decode(result.body);
requests.forEach((request) {
var model = Request();
model.user_id = request['user_id'];
model.concern = request['concern'];
model.message = request['message'];
setState(() {
_list.add(model);
});
});
}
return _list;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Bheekho App"),
),
body: FutureBuilder<List<Request>>(
future: _getAllRequest(),
builder:
(BuildContext context, AsyncSnapshot<List<Request>> snapshot) {
if (snapshot.hasData) {
return ListView.builder(
itemCount: snapshot.data.length,
itemBuilder: (context, index) {
return Column(
children: [
Card(
child: Text(snapshot.data[index].user_id),
),
],
);
});
} else {
return Container(
child: Text('loading...'),
);
}
},
));
}
}
This is my Model request.dart
class Request {
// ignore: non_constant_identifier_names
int request_id;
// ignore: non_constant_identifier_names
String user_id;
String concern;
String message;
}
This is Request_Service.dart
import 'package:bheekho_foundation/repository/repository.dart';
class RequestService {
Repository _repository;
RequestService() {
_repository = Repository();
}
getAllRequests() async {
return await _repository.httpGet('users');
}
}
This is Repository.dart
import 'package:http/http.dart' as http;
class Repository {
String _baseUrl = "http://localhost:8000/api";
httpGet(String api) async {
return await http.get(_baseUrl + "/" + api);
}
}
Erorr ScreenShot

Your snapshot.data[index].user_id is most likely null at this point.
To make sure you do not assign null to a Text widget, you can change it to something like this:
Text(
snapshot.data[index].user_id != null
? snapshot.data[index].user_id
: ""
)
This actually checks if the data is null, when it's not, it loads the snapshot data. In case it is, it loads an empty string.

Related

How to get the map data from the DocumentSnapshot, and get the field name?

Here are my current code and output.
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/material.dart';
class MedicalConditionList extends StatefulWidget {
const MedicalConditionList({Key? key}) : super(key: key);
#override
State<MedicalConditionList> createState() => _MedicalConditionListState();
}
class _MedicalConditionListState extends State<MedicalConditionList> {
final Stream<DocumentSnapshot> _medicalConditionStream = FirebaseFirestore
.instance
.collection('medical_condition')
.doc('b3936f64-8d90-4')
.snapshots();
List trueMedical = [];
bool contains = true;
#override
Widget build(BuildContext context) {
return StreamBuilder<DocumentSnapshot>(
stream: _medicalConditionStream,
builder: (context, AsyncSnapshot<DocumentSnapshot> snapshot) {
if (snapshot.hasError) {
return const Center(child: Text('Something went wrong'));
}
if (snapshot.connectionState == ConnectionState.waiting) {
return const Center(
child: CircularProgressIndicator(
color: Colors.red,
),
);
}
if (snapshot.connectionState == ConnectionState.active) {
var condition = snapshot.data?.data();
return Text(condition.toString());
}
return Container();
},
);
}
}
Output:
I have the data her but how can I do a listView of just the data with value of true, instead of print a whole bunch of data from my firebase.
I am thinking if I have a way to just get specific data like asthma when it is true by doing a map search such as
void main() {
var condition = {"asthma": true, "liver": false'};
usrMap.forEach((k,v) {
if(v == true){
print(k)
}
});
}
Something like this, maybe I am wrong. Main point is how to get just specific data.

DialogFlow Chatbot not showing the output

I am integrating DialogFlowtter the DialogFlow package of Google Cloud. It is not outputting any data to the screen PLease look into my code and help me out. Any hep would be aprreciated. Actually the code runs properly but when the if condition is check instead of hasdata it goes into haserror and just print "Error"
import 'dart:math';
import 'package:dialog_flowtter/dialog_flowtter.dart';
import 'package:flutter/material.dart';
class ChatBot extends StatefulWidget {
const ChatBot({Key? key}) : super(key: key);
#override
_ChatBotState createState() => _ChatBotState();
}
class _ChatBotState extends State<ChatBot> {
late DialogFlowtter? instance;
DialogAuthCredentials? credentials;
String? num;
getRandomSessionID() {
num = Random().nextInt(1000).toString();
}
getCred() async {
credentials =
await DialogAuthCredentials.fromFile('assets/credentials.json');
}
#override
void initState() {
// TODO: implement initState
getCred();
getRandomSessionID();
super.initState();
}
getQuery() async {
instance = DialogFlowtter(credentials: credentials!, sessionId: num!);
final QueryInput queryInput = QueryInput(
text: TextInput(
text: "Hi. How are you?",
languageCode: "en",
),
);
DetectIntentResponse response = await instance!.detectIntent(
queryInput: queryInput,
);
//print(response);
return response.text;
}
#override
Widget build(BuildContext context) {
return Column(
children: [
//Text(getQuery()),
Center(
child: FutureBuilder<dynamic>(
future: getQuery(),
builder: (
BuildContext context,
AsyncSnapshot<dynamic> snapshot,
) {
if (snapshot.connectionState == ConnectionState.waiting)
return Center(child: CircularProgressIndicator());
else if (snapshot.connectionState == ConnectionState.done) {
if (snapshot.hasError)
return Center(child: const Text('Error'));
else if (snapshot.hasData)
return Center(child: Text(snapshot.data!));
else {
return const Text('Empty data');
}
} else {
return Text('State: ${snapshot.connectionState}');
}
},
),
),
],
);
}
}

catch answer of WorkManager

I want to update the background color of my app in terms of result of my background task.
I use flutter_bloc and WorkManager.
I want my app to be blue during the action, and green if the result is good and red if my function throw an exception.
Or can I update my screen color in terms of result of my repo.getBattery call ?
Here in logs I can read workmanager.result error (bad url) but I can't catch it.
main.dart:
import 'package:batt/test_cubit.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:shared_preferences/shared_preferences.dart';
void main() {
WidgetsFlutterBinding.ensureInitialized();
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return BlocProvider(
create: (context) => TestCubit(),
child: MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
));
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
bool _sw_value = false;
TextEditingController _controller = TextEditingController(text: "url");
Future<Null> tmp() async{
SharedPreferences prefs = await SharedPreferences.getInstance();
setState(() {
_controller = TextEditingController(text: prefs.getString("url"));
});
}
#override
void initState(){
super.initState();
tmp();
}
#override
Widget build(BuildContext context) {
return BlocBuilder<TestCubit, TestState>(builder: (context, state) {
return Scaffold(
backgroundColor: state.status,
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.center,
children: [
TextField(
controller: _controller,
maxLines: null,
keyboardType: TextInputType.url,
onChanged: (url) =>
context.read<TestCubit>().urlChanged(url),
),
const SizedBox(
height: 50,
),
CupertinoSwitch(
value: _sw_value,
onChanged: (value){
setState(() {
_sw_value = value;
});
if (value == true){
BlocProvider.of<TestCubit>(context).validate();
}
else {
BlocProvider.of<TestCubit>(context).cancel();
}
}
),
],
),
),
);
});
}
}
and my test_cubit.dart:
import 'dart:async';
import 'package:battery_plus/battery_plus.dart';
import 'package:bloc/bloc.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:workmanager/workmanager.dart';
import 'data/Repository/battery_repo.dart';
import 'data/data_provider/battery_provider.dart';
import 'package:http/http.dart' as http;
part 'test_state.dart';
const fetchBackground = "fetchBackground";
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
switch (task) {
case fetchBackground:
var battery = Battery();
var batlevel = await battery.batteryLevel;
final urlFinal = inputData!["string"] + batlevel.toString();
try {
await repo.getBattery(urlFinal);
} catch (e) {
return Future.error("bad url");
}
break;
}
return Future.value(true);
});
}
final BatteryRepository repo = BatteryRepository(api: ServerAPI(http.Client()));
class TestCubit extends Cubit<TestState> {
TestCubit() : super(TestState("", Colors.grey));
urlChanged(String url) {
state.path = url;
}
validate() async {
if (state.path != "") {
final SharedPreferences _prefs = await SharedPreferences.getInstance();
_prefs.setString('url', state.path);
}
WidgetsFlutterBinding.ensureInitialized();
await Workmanager().cancelAll();
await Workmanager().initialize(
callbackDispatcher,
isInDebugMode: false,
);
state.status = Colors.blue;
emit(state);
try {
Workmanager().registerPeriodicTask("1", fetchBackground,
backoffPolicy: BackoffPolicy.exponential,
inputData: {
'string': state.path,
});
} catch (e) {
state.status = Colors.red;
emit(state);
}
Workmanager().registerPeriodicTask("2", fetchBackground,
initialDelay: const Duration(minutes: 5),
inputData: {
'string': state.path,
});
Workmanager().registerPeriodicTask("3", fetchBackground,
initialDelay: const Duration(minutes: 10),
inputData: {
'string': state.path,
});
state.status = Colors.green;
emit(state);
}
cancel() async {
await Workmanager().cancelAll();
state.status = Colors.pink;
emit(state);
}
}
please can you help me ? :)
I'm very beginner so I think my code is not good at all too :/

checking if a long sentence contains a short sentence from TextField, Dart

I want to search for a short sentence inside a long sentence ...
it is working fine with this demo:
String a = 'from first day i was very good';
String b = 'from first day';
print(a.contains(b));
result : true
but when I use TextField to enter a short sentence and check it if is exciting in a long sentence ...
TextField when I enter space between words doesn't show any result
Note: this app in the Arabic language and doesn't work on an android and IOS ... in English worked well in the IOS simulator but doesn't work on an android phone.
my all code:
import 'dart:convert';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:egyptian_ads_app/constant/constant.dart';
import 'package:egyptian_ads_app/pages/business_man_pages/business_man_page.dart';
import 'package:egyptian_ads_app/pages/starting_page/landing_service_page.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:share/share.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:url_launcher/url_launcher.dart';
class ItemModel {
ItemModel(
{this.id,
this.title,
this.imagePath,
this.about,
this.phoneNumber,
this.traderId,
this.type,
this.city});
int id;
String title;
String imagePath;
String about;
String phoneNumber;
int traderId;
String type;
String city;
factory ItemModel.fromJson(Map<String, dynamic> json) {
return new ItemModel(
id: json['id'],
title: json['name'],
imagePath: json["logo"]['url'],
about: json['about'],
phoneNumber: json['phone_number'],
traderId: json['trader_id'],
type: json['category']['type'],
// city: json['city'],
);
}
}
class InstantSearchPage extends StatefulWidget {
#override
_InstantSearchPageState createState() => _InstantSearchPageState();
}
class _InstantSearchPageState extends State<InstantSearchPage> {
TextEditingController _searchController = TextEditingController();
Future resultsLoaded;
List<ItemModel> _allResults = [];
List<ItemModel> _resultsList = [];
#override
void initState() {
super.initState();
_searchController.addListener(_onSearchChanged);
}
#override
void dispose() {
_searchController.removeListener(_onSearchChanged);
_searchController.dispose();
super.dispose();
}
#override
void didChangeDependencies() {
super.didChangeDependencies();
resultsLoaded = getUserDetails();
}
getUserDetails() async {
final String url = 'https://yallservice.com/api/v1/departments';
final response = await http.get(url);
final responseJson = json.decode(response.body);
var data = responseJson['data'];
setState(() {
for (Map user in data) {
_allResults.add(ItemModel.fromJson(user));
}
});
searchResultsList();
return "complete";
}
_onSearchChanged() {
searchResultsList();
}
searchResultsList() {
List<ItemModel> showResults = [];
if (_searchController.text != "") {
for (var tripSnapshot in _allResults) {
String title = tripSnapshot.about;
print(title + title);
if (title.contains(_searchController.text)) {
showResults.add(tripSnapshot);
}
}
} else {
showResults = List.from(_allResults);
}
setState(() {
_resultsList = showResults;
});
}
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
leading: BackButton(),
title: Container(
color: Colors.white,
child: TextField(
controller: _searchController,
decoration: InputDecoration(prefixIcon: Icon(Icons.search)),
),
),
),
body: Container(
color: Colors.grey.shade300,
child: Column(
children: <Widget>[
Expanded(
child: ListView.builder(
itemCount: _resultsList.length,
itemBuilder: (BuildContext context, int index) {
return Container(
color: Colors.white,
child: ListTile(
subtitle: Text(_resultsList[index].about),
));
// return Card(
// index: index,
// data: _resultsList,
// );
},
)),
],
),
),
);
}
}
This is due to the encoding of white spaces in RTL strings.
Try to trim the TextField text before you search for it.
Special trim method
String trim(String string) {
assert(string != null);
final stringList = string.characters.toList();
final whitespaces = ['8206', '8207', '32'];
while (whitespaces.contains(stringList.last.runes.join()))
stringList.removeLast();
while (whitespaces.contains(stringList.first.runes.join()))
stringList.remove(stringList.first);
return stringList.join();
}
Updated searchResultsList
searchResultsList() {
List<ItemModel> showResults = [];
if (_searchController.text != "") {
for (var tripSnapshot in _allResults) {
String title = tripSnapshot.about;
if (title.contains(trim(_searchController.text))) {
showResults.add(tripSnapshot);
}
}
} else {
showResults = List.from(_allResults);
}
setState(() {
_resultsList = showResults;
});
}
Ref: Text fields' values do not get trimmed correctly when textDirection: TextDirection.rtl #68093
Improvement
Your search is currently case-sensitive. Maybe you should make it case-insensitive?
searchResultsList() {
setState(() {
_resultsList = _searchController.text.isNotEmpty
? _allResults
.where((tripSnapshot) => tripSnapshot.about
.toLowerCase()
.contains(trim(_searchController.text).toLowerCase()))
.toList()
: List.from(_allResults);
});
}
I fixed the problem just by putting textDirection: TextDirection.rtl, to my TextField

how to get data from api(Map type) for dropdown option

I have a problem when i want to get data from api and show them in dropdown option, I can print data when i run my code but in dropdown option i have below error :
type '(dynamic) => DropdownMenuItem' is not a subtype of type '(String, dynamic) => MapEntry' of 'transform'
import 'package:flutter/material.dart';
import 'package:dropdownfield/dropdownfield.dart';
import 'package:http/http.dart' as http;
import 'dart:async';`enter code here`
import 'dart:convert';
class InBoundRate extends StatefulWidget {
#override
_InBoundRateState createState() => _InBoundRateState();
}
class _InBoundRateState extends State<InBoundRate> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: new Center(
child: new FutureBuilder(
future: GetInbound(),
builder: (BuildContext context, AsyncSnapshot<Map> snapshot) {
if (snapshot.hasData) {
Map content = snapshot.data ;
var sampleData = json.encode(content);
var json2 = JsonDecoder().convert(sampleData);
// print(json2['data']['countries']);
return DropdownButton(
items: json2.map(
(item) => DropdownMenuItem(
value: item['data']['countries'],
child: Text(item['data']['countries'])),
// onChanged: (Users value) {
// setState(() {
// _currentUser = value;
// });
// }
),
isExpanded: false,
//value: _currentUser,
hint: Text('Select User'),
);
} else {
return new Container();
}
}),
),
);
}
}
Future<Map> GetInbound() async {
String apiUrl = 'http://homaexpressco.ir/api/getRatesInformation2';
http.Response response = await http.get(apiUrl);
var res = json.decode(response.body);
return res;
}

Categories

Resources