Can't Update a String Variable After initializing it in Flutter - string

I want to Update the new value of the 'holecode' variable in 'inputform.dart' then get this new value to the 'otpscreen.dart'
The Problem that in each time I try to get the value of the 'holecode' string variable I get the 'default' value which I initialize it.I tried to make the 'holecode' variable as late String holecode; but it return Null in the second Screen in each time I try to get it's value.
inputform.dart:
import 'package:flutter/material.dart';
class Inputform extends StatefulWidget {
List<String> code = ["","","","","",""];
String holeCode = "default";
#override
State<Inputform> createState() => InputformState();
}
class InputformState extends State<Inputform> {
#override
Widget build(BuildContext context) {
return TextFormField(
onChanged: (value) {
setState(() {
widget.code[0] = value;
widget.holeCode = widget.code[0] + 222205;
});
if (value.length == 1) {
FocusScope.of(context).nextFocus();
}
}
),
},
otp.dart:
import 'package:flutter/material.dart';
class OtpVerification extends StatefulWidget {
#override
State<StatefulWidget> createState() => Otp();
}
class Otp extends State<OtpVerification> {
final Inputform ani= new Inputform ();
#override
Widget build(BuildContext context) {
return Scaffold(
child:
FlatButton(
onPressed: () {
// trying to print the new value in this screen but it
//return the default value 'default'
print(ani.holeCode);
),
);
}

Try this:
Have your InputForm like so:
class Inputform extends StatefulWidget {
final ValueChanged<String> onHoleCodeChanged;
const Inputform({
Key? key,
required this.onHoleCodeChanged,
}) : super(key: key);
#override
State<Inputform> createState() => InputformState();
}
class InputformState extends State<Inputform> {
List<String> code = ["", "", "", "", "", ""];
String holeCode = "default";
#override
Widget build(BuildContext context) {
return TextFormField(onChanged: (value) {
setState(() {
code[0] = value;
holeCode = code[0] + "222205";
widget.onHoleCodeChanged(holeCode);
});
if (value.length == 1) {
FocusScope.of(context).nextFocus();
}
});
}
}
And have your OTP class like so:
class OtpVerification extends StatefulWidget {
#override
State<StatefulWidget> createState() => Otp();
}
class Otp extends State<OtpVerification> {
late Inputform ani;
#override
void initState() {
ani = Inputform(
onHoleCodeChanged: (v) {
setState(() {
aniHoleCode = v;
});
},
);
super.initState();
}
String aniHoleCode = "";
#override
Widget build(BuildContext context) {
return Scaffold(
body: FlatButton(
child: Text("Button"),
onPressed: () {print(aniHoleCode);},
),
);
}
}

Related

Flutter version 1.71.1 I am getting this error "type 'Null' is not a subtype of type 'List'<String> in type cast"

I've include the operator ?? and it still failed. Here is my code:
import 'package:flutter/material.dart';
import './question.dart';
import './answer.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
#override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
//_answerQuestion function passed to widget below
void _answerQuestion() {
//Must use setState() function to change question on UI
setState(() {
_questionIndex = _questionIndex + 1;
});
print(_questionIndex);
}
#override
Widget build(BuildContext context) {
//List string questions with var inside of []
var questions = [
//This is how to develp a "MAP" = list of questions & answers
{
'questionText': 'Who created Fluter?',
'answer': ['Google', 'Yahoo', 'Amtrak', 'Disney'],
},
{
'questionText': 'What is your favorite class',
'answer': ['Java', 'Mobile App', 'Dart', 'DevOps'],
},
{
'questionText': 'What is your favorite Fluter feature',
'answer': ['Class', 'Functions', 'Dart', 'Widgets'],
},
];
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Flutter Quiz'),
),
body: Column(
children: [
Question(
(questions[_questionIndex] ['questionText']) as String,
),
//... = spread operator to take a nested list and include in existing list
**...((questions[_questionIndex] ['answers']) as List<String>)**
.map((answer) {
return Answer(_answerQuestion, answer);
}).toList()
],
),
),
);
}
}

Failed Assertion 'url != null': is not true Error

I am still new to flutter and am learning building apps. I have been trying to run this code for but every time I run it I get a red screen on the android emulator and an error which goes "Failed Assertion: Line 22 pos 14 'url != null': is not true".
This is my main file which runs the app
import "package:flutter/material.dart";
import "src/app.dart";
voidmain() {
runApp(MyApp());
}
My App file has this code
import 'package:flutter/material.dart';
import 'package:http/http.dart' show get;
import 'models/image_models.dart';
import 'dart:convert';
import 'widgets/image_list.dart';
class MyApp extends StatefulWidget {
createState() {
return AppState();
}
}
class AppState extends State<MyApp> {
int counter = 0;
List<ImageModels> images = [];
void fetchImage() async {
counter++;
var response =
await get('http://jsonplaceholder.typicode.com/photos/$counter');
var imagemodel = ImageModels.fromjson(json.decode(response.body));
setState(() {
images.add(imagemodel);
});
}
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: ImageList(images),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
fetchImage();
}),
appBar: AppBar(title: Text("Ola Amigo!")),
));
}
}
Heres the ImageModel Class
class ImageModels {
int id;
String url;
String title;
ImageModels(this.id, this.url, this.title);
ImageModels.fromjson(Map<String, dynamic> parsedjson) {
id = parsedjson[id];
title = parsedjson[title];
url = parsedjson[url];
}
}
and lastly the ImageList
import 'package:flutter/material.dart';
import '../models/image_models.dart';
class ImageList extends StatelessWidget {
final List<ImageModels> image;
ImageList(this.image);
Widget build(context) {
return ListView.builder(
itemCount: image.length,
itemBuilder: (context, int index) {
return buildImage(image[index]);
});
}
Widget buildImage(ImageModels image) {
return Container(
decoration: BoxDecoration(
border: Border.all(color: Colors.grey)
),
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
child: Image.network(image.url),
);
}
}
Can someone please take a look at it and tell me what am I doing wrong and how can I resolve this issue.
Thank you
You can copy paste run full code below
You have error in ImageModels, please revise to
code snippet
factory ImageModels.fromjson(Map<String, dynamic> parsedjson) => ImageModels(
parsedjson["id"],
parsedjson["url"],
parsedjson["title"],
);
working demo
full code
import 'dart:convert';
import 'package:http/http.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
createState() {
return AppState();
}
}
class AppState extends State<MyApp> {
int counter = 0;
List<ImageModels> images = [];
void fetchImage() async {
counter++;
var response =
await get('https://jsonplaceholder.typicode.com/photos/$counter');
print(response.body);
var imagemodel = ImageModels.fromjson(json.decode(response.body));
print(imagemodel.url);
setState(() {
images.add(imagemodel);
print(images[0].url);
});
}
Widget build(context) {
return MaterialApp(
home: Scaffold(
body: ImageList(images),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
fetchImage();
}),
appBar: AppBar(title: Text("Ola Amigo!")),
));
}
}
class ImageModels {
int id;
String url;
String title;
ImageModels(this.id, this.url, this.title);
factory ImageModels.fromjson(Map<String, dynamic> parsedjson) => ImageModels(
parsedjson["id"],
parsedjson["url"],
parsedjson["title"],
);
}
class ImageList extends StatelessWidget {
final List<ImageModels> image;
ImageList(this.image);
Widget build(context) {
return ListView.builder(
itemCount: image.length,
itemBuilder: (context, int index) {
print(image[index].url);
return buildImage(image[index]);
});
}
Widget buildImage(ImageModels image) {
return Container(
decoration: BoxDecoration(border: Border.all(color: Colors.grey)),
padding: EdgeInsets.all(20.0),
margin: EdgeInsets.all(20.0),
child: Image.network(image.url),
);
}
}

Use js library in flutter web

I need widget with bpmn.js view: https://github.com/bpmn-io/bpmn-js
Used HtmlElementView:
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory('bpmn_view', (int viewId) => element);
return Column(
children: <Widget>[
Expanded(
child: HtmlElementView(key: UniqueKey(), viewType: "bpmn_view")),
],
);
With js:
const html = '''
<div id="canvas">canvas</div>
<script>
(function () {
window.addEventListener('view_bpmn', function (e) {
var bpmnJS = new BpmnJS({
container: "#canvas"
});
bpmnJS.importXML(e.details);
}, false);
}());
</script>
''';
element.setInnerHtml(html,
validator: NodeValidatorBuilder.common()..allowElement('script'));
But I get error when it execute:
VM4761 bpmn-viewer.development.js:18864 Uncaught TypeError: Cannot read property 'appendChild' of null
at Viewer.BaseViewer.attachTo (VM4761 bpmn-viewer.development.js:18864)
at Viewer.BaseViewer._init (VM4761 bpmn-viewer.development.js:18911)
at Viewer.BaseViewer (VM4761 bpmn-viewer.development.js:18454)
at new Viewer (VM4761 bpmn-viewer.development.js:19082)
at <anonymous>:3:25
at main.dart:185
at future.dart:316
at internalCallback (isolate_helper.dart:50)
And I can't set selector for BpmnJS like:
var bpmnJS = new BpmnJS({
container: "document.querySelector('flt-platform-view').shadowRoot.querySelector('#canvas')";
});
How can I make it work?
Since BpmnJS container parameter accepts DOMElement type value, we can pass querySelector's result directly:
_element = html.DivElement()
..id = 'canvas'
..append(html.ScriptElement()
..text = """
const canvas = document.querySelector("flt-platform-view").shadowRoot.querySelector("#canvas");
const viewer = new BpmnJS({ container: canvas });
""");
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory('bpmn-view', (int viewId) => _element);
BpmnJS module should be attached to index.html file (in your project's top-level web folder):
<!DOCTYPE html>
<head>
<title>BpmnJS Demo</title>
<script defer src="main.dart.js" type="application/javascript"></script>
<script src="https://unpkg.com/bpmn-js#6.4.2/dist/bpmn-navigated-viewer.development.js"></script>
</head>
...
Here is full code:
import 'dart:ui' as ui;
import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';
class BpmnDemo extends StatefulWidget {
#override
_BpmnDemoState createState() => _BpmnDemoState();
}
class _BpmnDemoState extends State<BpmnDemo> {
html.DivElement _element;
#override
void initState() {
super.initState();
_element = html.DivElement()
..id = 'canvas'
..append(html.ScriptElement()
..text = """
const canvas = document.querySelector("flt-platform-view").shadowRoot.querySelector("#canvas");
const viewer = new BpmnJS({ container: canvas });
const uri = "https://cdn.staticaly.com/gh/bpmn-io/bpmn-js-examples/dfceecba/url-viewer/resources/pizza-collaboration.bpmn";
fetch(uri).then(res => res.text().then(xml => viewer.importXML(xml)));
""");
// ignore: undefined_prefixed_name
ui.platformViewRegistry
.registerViewFactory('bpmn-view', (int viewId) => _element);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: HtmlElementView(key: UniqueKey(), viewType: "bpmn-view")),
);
}
}
UPDATE:
This example shows how to load a diagram from dart code and uses dart:js library:
import 'dart:ui' as ui;
import 'dart:js' as js;
import 'package:universal_html/html.dart' as html;
import 'package:flutter/material.dart';
class BpmnDemo extends StatefulWidget {
#override
_BpmnDemoState createState() => _BpmnDemoState();
}
class _BpmnDemoState extends State<BpmnDemo> {
html.DivElement _element;
js.JsObject _viewer;
#override
void initState() {
super.initState();
_element = html.DivElement();
_viewer = js.JsObject(
js.context['BpmnJS'],
[
js.JsObject.jsify({'container': _element})
],
);
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory('bpmn-view', (int viewId) => _element);
loadDiagram('assets/pizza-collaboration.bpmn');
}
loadDiagram(String src) async {
final bundle = DefaultAssetBundle.of(context);
final xml = await bundle.loadString(src);
_viewer.callMethod('importXML', [xml]);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(child: HtmlElementView(key: UniqueKey(), viewType: "bpmn-view")),
);
}
}
UPDATE 2:
Certain complications with calling methods from js library can arise when HtmlElementView uses IFrame element. In this case we can try two options:
Store IFrame context on dart side and then use callMethod with saved context.
Use postMessage method to communicate with IFrame
import 'dart:ui' as ui;
import 'dart:js' as js;
import 'dart:html' as html;
import 'package:flutter/material.dart';
class IFrameDemoPage extends StatefulWidget {
#override
_IFrameDemoPageState createState() => _IFrameDemoPageState();
}
class _IFrameDemoPageState extends State<IFrameDemoPage> {
html.IFrameElement _element;
js.JsObject _connector;
#override
void initState() {
super.initState();
js.context["connect_content_to_flutter"] = (content) {
_connector = content;
};
_element = html.IFrameElement()
..style.border = 'none'
..srcdoc = """
<!DOCTYPE html>
<head>
<script>
// variant 1
parent.connect_content_to_flutter && parent.connect_content_to_flutter(window)
function hello(msg) {
alert(msg)
}
// variant 2
window.addEventListener("message", (message) => {
if (message.data.id === "test") {
alert(message.data.msg)
}
})
</script>
</head>
<body>
<h2>I'm IFrame</h2>
</body>
</html>
""";
// ignore:undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'example',
(int viewId) => _element,
);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
actions: [
IconButton(
icon: Icon(Icons.filter_1),
tooltip: 'Test with connector',
onPressed: () {
_connector.callMethod('hello', ['Hello from first variant']);
},
),
IconButton(
icon: Icon(Icons.filter_2),
tooltip: 'Test with postMessage',
onPressed: () {
_element.contentWindow.postMessage({
'id': 'test',
'msg': 'Hello from second variant',
}, "*");
},
)
],
),
body: Container(
child: HtmlElementView(viewType: 'example'),
),
);
}
}

using multiple compute in flutter

Is it possible to use multiple compute at the same time?
I'd like to call a heavy function on a list, which I want to run in parallel, but it crashes the app without any error message.
Am I supposed to do only one compute call at a time?
Here's my test code that crashes often (but not always).
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(home: MyHomePage());
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
Future<List<int>> f;
#override
void initState() {
super.initState();
f = getFutures();
}
Future<List<int>> getFutures() async {
List<int> output = [];
List<Future<int>> futures = [];
for (int i = 0; i < 100; ++i) {
print("call getFuture");
futures.add(getFuture());
}
for (int i = 0; i < futures.length; ++i) {
var f = await futures[i];
output.add(f);
}
return output;
}
Future<int> getFuture() async {
print("call compute");
var i = await compute(count, 1000000000);
return i;
}
static int count(int max) {
print("start count");
int j;
for (int i = 0; i < max; ++i) {
j = i;
}
return j;
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("test")),
body: FutureBuilder<List<int>>(
future: f,
builder: (context, snapshot) {
switch (snapshot.connectionState) {
case ConnectionState.done:
print(snapshot);
return ListView.builder(
itemCount: 100,
itemBuilder: (context, index) {
return Text("snapshot: ${snapshot.data[index]}");
});
break;
default:
return Center(child: CircularProgressIndicator());
}
}),
);
}
}

Is there a way to send a request after the user has stopped typing?

I am looking for a way to send an API request after the user has stopped typing for X amount of seconds.
The way I am sending the request is through the onTextChanged callback, however, that sends a request on every key press
I have seen ways to do this with a timeout in React, however, I am relatively new to flutter so any help would be appreciated
you can use the below code to do this:
import 'package:flutter/material.dart';
import 'dart:async';
class Test extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _TestState();
}
}
class _TestState extends State<StatefulWidget> {
Timer searchOnStoppedTyping;
_onChangeHandler(value ) {
const duration = Duration(milliseconds:800); // set the duration that you want call search() after that.
if (searchOnStoppedTyping != null) {
setState(() => searchOnStoppedTyping.cancel()); // clear timer
}
setState(() => searchOnStoppedTyping = new Timer(duration, () => search(value)));
}
search(value) {
print('hello world from search . the value is $value');
}
#override
Widget build(BuildContext context) {
return TextField(
onChanged: _onChangeHandler,
decoration: InputDecoration(
hintText: 'Search ....'
),
);
}
}
The usual way to do this in Flutter is using RxDart and its debounce() method. It allows to wait a small period before launching a specific call.
In the following full example you see it in action with a time of 1 second. In the example, a message is shown where the call to the server should be dispatched.
import 'package:flutter/material.dart';
import 'package:rxdart/rxdart.dart';
void main() => runApp(new MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => new _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final subject = new PublishSubject<String>();
bool isLoading = false;
GlobalKey<ScaffoldState> scaffoldKey = new GlobalKey();
void _textChanged(String text) {
if (text.isEmpty) {
setState(() {
isLoading = false;
});
return;
}
setState(() {
isLoading = true;
});
scaffoldKey.currentState.showSnackBar(new SnackBar(
content: new Text("Search for ${text}"),
));
}
#override
void initState() {
super.initState();
subject.stream.debounce(new Duration(milliseconds: 1000)).listen(_textChanged);
}
#override
void dispose() {
subject.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
return new Scaffold(
key: scaffoldKey,
appBar: new AppBar(
title: new Text("Debounce demo"),
),
body: new Container(
padding: new EdgeInsets.all(8.0),
child: new Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
new TextField(
decoration: new InputDecoration(
hintText: 'Type text to search',
),
onChanged: (string) => (subject.add(string)),
),
isLoading
? Padding(
padding: const EdgeInsets.all(20.0),
child: new CircularProgressIndicator(),
)
: new Container(),
],
),
),
);
}
}
You can see this code in action in the following article and code by Norbert Kozsir

Resources