How to Send data as JSON over to MQTT broker in flutter - flutter

return RaisedButton(
color: Colors.green,
disabledColor: Colors.grey,
textColor: Colors.white,
disabledTextColor:Colors.black38 ,
child: Text("Break"),
onPressed: state == MQTTAppConnectionState.connectedSubscribed
? () {
setState(() {
value = 0;
action = jsonData;
});
publishMessage(action);
}
: null, //
);
}
I have multiple buttons in my app that passes different message to mqtt client
I want to pass different json data to mqtt client for each button
sample json data for single button
{
"Motor":"BLDC motor",
"Acc": 70,
"F/R": "Forward",
"Break":"False",
"Key":"True"
}
help me to pass single json data to mqtt client when the button is pressed

Pass the values in the publish method and make this changes there it will work
return RaisedButton(
color: Colors.green,
disabledColor: Colors.grey,
textColor: Colors.white,
disabledTextColor:Colors.black38 ,
child: Text("Break"),
onPressed: state == MQTTAppConnectionState.connectedSubscribed
? () {
setState(() {
break1 = "True";
value = 0;
});
publish(break1);
}
: null,//
);
void publish(String break1) {
final MqttClientPayloadBuilder builder = MqttClientPayloadBuilder();
builder.addString(
json.encode(
{
"break": "$break1",
}
)
);
_client!.publishMessage(_topic, MqttQos.exactlyOnce, builder.payload!);}

Related

How to place a Loader on the screen while an API action is being performed in Flutter

I am trying to show a loader when a form is submitted to the server so that there isn't another submission of the same form until and unless the API sends back a response. I have tried something like the below code but it just doesn't seem to work as the Circular Progress indicator seems to not show up and rather, the screen remains as it is until the server sends back a response. As a result of this, the user gets confused as to whether or not their requests got submitted, and in the process, they end up posting the same form another time only to find out later that their were multiple submissions. I will include snippets of the code that has the CircularProgressIndicator() to prevent another submission and the widget that has the API call code.
bool isSelected = false;
isSelected
? const CircularProgressIndicator() : Container(
child: Center(
child: AppButtonStyle(
label: 'Submit',
onPressed: () {
if (_key.currentState!.validate()) { //This is the key of the Form that gets submitted
setState(() {
isSelected = true;
});
List<String> date = [
dateFormat.format(_dateTimeStart!).toString(),
dateFormat.format(_dateTimeEnd!).toString()
];
Map<String, dynamic> data = {
'leave_type': _selectedItem,
'dates': date,
'description': add
};
if (kDebugMode) {
print('DATA: $data');
}
Provider.of<LeaveViewModel>(context, listen: false)
.postLeaveRequests(data, context) //This here makes the API call
.then((value) {
setState(() {
isSelected = false;
_textController.clear();
_dateTimeStart = null;
_dateTimeEnd = null;
});
});
}
},
),
),
)
The API module:
class LeaveViewModel with ChangeNotifier {
final leaveRepository = LeaveRequestRepository();
Future<void> postLeaveRequests(dynamic data, BuildContext context) async {
SharedPreferences localStorage = await SharedPreferences.getInstance();
String authToken = localStorage.getString('token').toString();
leaveRepository.requestLeave(authToken, data).then((value) {
print('LEAVEEEEEE: $value');
Flushbar(
duration: const Duration(seconds: 4),
flushbarPosition: FlushbarPosition.BOTTOM,
borderRadius: BorderRadius.circular(10),
icon: const Icon(Icons.error, color: Colors.white),
// margin: const EdgeInsets.fromLTRB(100, 10, 100, 0),
title: 'Leave Request Submitted',
message: value.data.toString()
).show(context);
}).onError((error, stackTrace) {
Flushbar(
duration: const Duration(seconds: 4),
flushbarPosition: FlushbarPosition.BOTTOM,
borderRadius: BorderRadius.circular(10),
icon: const Icon(Icons.error, color: Colors.white),
// margin: const EdgeInsets.fromLTRB(100, 10, 100, 0),
title: 'Leave Request Failed',
message: error.toString()
).show(context);
});
}
}
Any help will be appreciated. Also, I'm open to the concept of using easy_loader 2.0.0 instead of CicularProgressIndicator() and would be very glad to read suggestions about it's usage in my code.
One problem in your code seems to be that you define isSelected in your build method. Every time you call setState, the build method is called to regenerate the widgets. And with each new call isSelected gets false as initial value. Define isSelected as class variable, so that it is not always on false.
The more elegant solution would be to work with a FutureBuilder
https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

Flutter Button statemanagement using provider

In my flutter application I have a button for follow and unfollow a user.
buttonstate.isSelected && widget.user!.isFollowing == true
? ElevatedButton(
onPressed: () async {
await unfollowuser(widget.user!.id); //Api Call
},
child: Text(
'Following',
style: TextStyle(
color: Theme.of(context).disabledColor,
),
),
)
: ElevevatedButton(
onPressed: () async {
buttonstate.setButtonState(true);
await followuser(widget.user!.id); //Api Call
},
child: Text(
'Follow',
style: TextStyle(
color: Theme.of(context).accentColor,
),
),
),
My objective is whenever the button is pressed I want the Api call to happen as well as the state of the button should change from 'Follow' to 'Following'. Now the Api gets called, but the button wont change to 'following'. After the page is refreshed, button changes to 'following'. How can i manage state of the button using provider??
Ive created a provider for this purpose as follows
import 'package:flutter/material.dart';
class ButtonProvider with ChangeNotifier {
bool isSelected = false;
void setButtonState(bool value) {
isSelected = value;
notifyListeners();
}
bool? get buttondata {
return isSelected;
}
}

Flutter Progress_state_button - how to change button state

I am trying to use the progress state button in flutter. From the pub.dev docs, the widget should be set up as follows
Widget buildTextWithIcon() {
return ProgressButton.icon(iconedButtons: {
ButtonState.idle: IconedButton(
text: "Send",
icon: Icon(Icons.send, color: Colors.white),
color: Colors.deepPurple.shade500),
ButtonState.loading:
IconedButton(text: "Loading", color: Colors.deepPurple.shade700),
ButtonState.fail: IconedButton(
text: "Failed",
icon: Icon(Icons.cancel, color: Colors.white),
color: Colors.red.shade300),
ButtonState.success: IconedButton(
text: "Success",
icon: Icon(
Icons.check_circle,
color: Colors.white,
),
color: Colors.green.shade400)
}, onPressed: onPressedIconWithText, state: stateTextWithIcon);
}
I have a function (already written and working fine) that I want to run when the button is clicked, changing the button state to ButtonState.loading then to ButtonState.success then back to ButtonState.idle. See below the function stated on the pub.dev site.
void onPressedIconWithText() {
switch (stateTextWithIcon) {
case ButtonState.idle:
stateTextWithIcon = ButtonState.loading;
Future.delayed(Duration(seconds: 1), () {
setState(() {
stateTextWithIcon = Random.secure().nextBool()
? ButtonState.success
: ButtonState.fail;
});
});
break;
case ButtonState.loading:
break;
case ButtonState.success:
stateTextWithIcon = ButtonState.idle;
break;
case ButtonState.fail:
stateTextWithIcon = ButtonState.idle;
break;
}
setState(() {
stateTextWithIcon = stateTextWithIcon;
});
}
}
However, I am new to coding, and have no idea at all on how to use "breaks" or to change the button state. Could anybody help with advising on how i would insert my funcion (let's say its just void runFunction() in to the above code, changing the state from idle --> loading (onPressed) --> success --. idle.
Any help would be greatly appreciated
You could use setState to update the values for stateTextWithIcon
ButtonState stateTextWithIcon = ButtonState.idle;
Widget buildTextWithIcon() {
return ProgressButton.icon(iconedButtons: {
ButtonState.idle: IconedButton(
text: "Send",
icon: Icon(Icons.send, color: Colors.white),
color: Colors.deepPurple.shade500),
ButtonState.loading:
IconedButton(text: "Loading", color: Colors.deepPurple.shade700),
ButtonState.fail: IconedButton(
text: "Failed",
icon: Icon(Icons.cancel, color: Colors.white),
color: Colors.red.shade300),
ButtonState.success: IconedButton(
text: "Success",
icon: Icon(
Icons.check_circle,
color: Colors.white,
),
color: Colors.green.shade400)
}, onPressed: (){
progressButton()
},
state: stateTextWithIcon,
);
this is the fucntion handled by my onPressed
Future progressButton() async {
setState(() {
//sets the state of stateTextWithIcon to loading once button is pressed
stateTextWithIcon = ButtonState.loading;
});
var url = 'https://google.com';
final response = await http.get(url);
if (response.statusCode == 200 || response.statusCode == 201) {
setState(() {
//sets the state of stateTextWithIcon to success if whatever request made was successful
stateTextWithIcon= ButtonState.success;
});
} else {
setState(() {
//sets the state of stateTextWithIcon to fail if the request was unsuccessful
stateTextWithIcon = ButtonState.fail;
});
}
}

flutter like_button on tap increment the value in the server

I used the like button flutter package from https://pub.dev/packages/like_button
to include like button to my list view from api. I have a table which is contain the count of likes and I show them in every item. now I want to increment the count of likes after tap on like button, but the type of function is bool and I can pass item id as parameter. so please help to solve this issue
LikeButton(
onTap: onLikeButtonTapped,
size: 20,
circleColor:
CircleColor(start: Colors.pink, end: Colors.pinkAccent),
bubblesColor: BubblesColor(
dotPrimaryColor: Colors.red,
dotSecondaryColor: Colors.redAccent,
),
likeBuilder: (bool isLiked) {
return Icon(
Icons.favorite,
color: isLiked ? Colors.pink : Colors.pink[300],
size: 20,
);
},
likeCount: news[index].count_like,
countBuilder: (int count, bool isLiked, String text) {
var color = isLiked ? Colors.grey[700] : Colors.grey[600];
Widget result;
if (count == 0) {
result = Text(
"love",
style: TextStyle(color: color),
);
} else
result = Text(
text,
style: TextStyle(color: color),
);
return result;
},
),
and here is the predefined function which is provided by the package developer
Future<bool> onLikeButtonTapped(bool isLiked) async{
<!-- send your request here -->
<!-- final bool success= await sendRequest(); -->
<!-- if failed, you can do nothing -->
<!-- return success? !isLiked:isLiked; -->
return !isLiked;
}
I am not sure if this could solve your problem, but I also had a similar situation to pass arguments through the function so I modified the function and somehow solved the issue. Hope it helps.
I used ontap like this:
onTap: (isLiked) {
return changedata(
isLiked,
);
},
and then the function,
Future<bool> changedata(status) async {
//your code
return Future.value(!status);
}
}

How to code a flutter function which runs if and only changes detected?

I'm doing an app in flutter which has 3 flat buttons able to set values(1-3) when they pressed. Now I need a function that can print some message according to the values it received.
value == 3 ? print("happy") : print("press any button");
value == 2 ? print("normal") : print("press any button");
value == 1 ? print("worst") : print("press any button");
NOTE: onpressed function of each button can only set values. The function to detect change must be run independently somewhere which is not returning any widgets inside it. Simply onChanged() function for a group of buttons.
For reference:
Widget flatbuttongrop(){
return Form(
child: Row(
children: <Widget>[
FlatButton(
shape: CircleBorder(),
color: Colors.red,
child: Text("H"),
onPressed: () {
value = 1;
// return value = 1;
},
),
FlatButton(
shape: CircleBorder(),
color: Colors.yellow,
child: Text("N"),
onPressed: (){
// return value = 2;
value = 2;
},
),
FlatButton(
shape: CircleBorder(),
color: Colors.green,
child: Text("S"),
onPressed: (){
value = 3;
},
),
],
),
onChanged: ()
{
//If any flatbutton pressed then it must indicate here.
},
);
}
Thanks in advance.
I assume you are using Stateful Widget if yes, following below steps will solve your problem
You could use the String function for that
String getStringValue(int value){
if(value == 1)
return "Worst"
else if(value == 2)
return "Normal"
else if(value == 3)
return "Happy"
else
return "Press Any Button"
}
And in the onPressed you could update your code like this
onPressed: (){
setState((){
value = someIntValue;
});
}
And wherever you need to use that String just call
getStringValue(someIntValue)