How do I print to the console with Dart? - dart

I'd like my Dart program to print to the dev console of my browser. How can I print to the console (DevTools's console, for example) ?

Use print() to print a string to the console of your browser:
import 'dart:html';
main() {
var value = querySelector('input').value;
print('The value of the input is: $value');
}
You will see a message printed to the developer console.

If you simlpy want to print text to the console you can use print('Text').
But if you want to access the advanced fatures of the DevTools console you need to use the Console class from dart:html: Console.log('Text').
It supports printing on different levels (info, warn, error, debug). It also allows to print tables and other more advanced features. Note that these are not supported in every browser! It's sad that the documentation about the Console class is incomplete, but you can take a look at the documentation of Chrome here and here.

There is log() from import 'dart:developer' library also.
example:
int name = "Something";
log("ClassName: successfully initialized: $name");
//output
[log] ClassName: successfully initialized: Something
Please note that log and debugPrint taking a value of String not like print. So, you have to add .toString() at the end or use with String interpolation like I used in above example.
From doc:
You have two options for logging for your application. The first is to
use stdout and stderr. Generally, this is done using print()
statements, or by importing dart:io and invoking methods on stderr and
stdout. For example:
stderr.writeln('print me');
If you output too much at once, then Android sometimes discards some
log lines. To avoid this, use debugPrint(), from Flutter’s foundation
library. This is a wrapper around print that throttles the output to a
level that avoids being dropped by Android’s kernel.
The other option for application logging is to use the dart:developer
log() function. This allows you to include a bit more granularity and
information in the logging output. Here’s an example:
import 'dart:developer' as developer;
void main() {
developer.log('log me', name: 'my.app.category');
developer.log('log me 1', name: 'my.other.category');
developer.log('log me 2', name: 'my.other.category');
}
You can also pass application data to the log call. The convention for
this is to use the error: named parameter on the log() call, JSON
encode the object you want to send, and pass the encoded string to the
error parameter.
import 'dart:convert'; import 'dart:developer' as developer;
void main() {
var myCustomObject = ...;
developer.log(
'log me',
name: 'my.app.category',
error: jsonEncode(myCustomObject),
);
}
If viewing the logging output in DevTool’s logging view, the JSON
encoded error param is interpreted as a data object and rendered in
the details view for that log entry.
read more(It's cool like a tutorial).

If you are here for Flutter, there's debugPrint which you should use.
Here's the doc text for the same.
/// Prints a message to the console, which you can access using the "flutter"
/// tool's "logs" command ("flutter logs").
/// By default, this function very crudely attempts to throttle the rate at
/// which messages are sent to avoid data loss on Android. This means that
/// interleaving calls to this function (directly or indirectly via, e.g.,
/// [debugDumpRenderTree] or [debugDumpApp]) and to the Dart [print] method can
/// result in out-of-order messages in the logs.
You might get SDK version constraint as it is only for 2.2 and above.

Dart print() function works differently in different environment.
print() when used in console based application it outputs in the terminal console
print() when used in web based application it outputs to the developer console.
void main() {
print("HTML WebApp");
}

The only way I know , which is supported by dartpad ,is through using print();
by the way Dart uses the ${} syntax for expressions, or just a $ for single value.
ex:-
int x=3;
print('hello world') ;
print(x) ;
print('x = $x') ;
and her is the link for the documentation
print method!

Related

Dart How to load file in runtime

I'm writing a discord bot using the nyxx library and want use dynamic file import for load command info and handler. But, after 5 hours of searching with Google, I didn't find anything to help me do that.
In Node.js, I can use require() or import() for it: Does the dart have something like that?
A small code snippet, showing what I want do:
this.commands = new Collection();
fs.readdirSync('./src/commands').filter(( f ) => f.endsWith( '.js' )).forEach((file) => {
const command = require(`../commands/${file}`);
this.commands.set( command.info.name, command );
});
Is it possible to do this or not? (I don't like to write many imports for commands and register it in lib.)
You can in theory use Isolate.spawnUri to spawn external Dart programs to run in its own Isolate instances that can then communicate back to the main program using SendPort.
It does, however, come with some limitations. E.g. it is very limited what types of objects you can send though SendPort when using spawnUri since the two programs does not share any type information (compared to Isolate.spawn which does allow you to send your own custom types). The documented types you can send can be found here:
Null
bool
int
double
String
List or Map (whose elements are any of these)
TransferableTypedData
SendPort
Capability
https://api.dart.dev/stable/2.17.6/dart-isolate/SendPort/send.html
But it does allow us to make some kind of protocol and you can create some helper class around this to handle the conversion of a known object structure into e.g. Map<String, Object>.
A small example that works with Dart VM would be:
Your command implemented as: command.dart
import 'dart:isolate';
void main(List<String> arguments, Map<String, Object> message) {
final userName = message['username'] as String;
final sendPort = message['port'] as SendPort;
sendPort.send('Hi $userName. '
'You got a message from my external command program!');
}
Your server that calls your command: server.dart
import 'dart:isolate';
void main() {
final recievePort = ReceivePort();
recievePort.listen((message) {
print('Got the following message: $message');
recievePort.close();
});
Isolate.spawnUri(Uri.file('command.dart'), [], {
'username': 'julemand101',
'port': recievePort.sendPort,
});
}
If running this with: dart server.dart you, hopefully, get:
Got the following message: Hi julemand101. You got a message from my external command program!
If you want to compile your application, you can do so by doing the following. You need to compile the command.dart, since a compiled Dart program does not understand how to read Dart code.
dart compile exe server.dart
dart compile aot-snapshot command.dart
You should here change Uri.file('command.dart') to Uri.file('command.aot') since the file-extension for aot-snapshot are .aot.
If everything works, you should be able to see:
> .\server.exe
Got the following message: Hi julemand101. You got a message from my external command program!

In Dart, how do I add a ">>" before the input created by stdin.readLineSync()?

I'm writing a Dart console app for the first time and I've searched the Internet everywhere and can't find the proper answer.
In Python, the function raw_input(); takes user input from stdin in a similar way to Dart's stdin.readLineSync();, however raw_input(); takes a parameter: If I do something like raw_input(">>");, the CLI does something like:
>> _
In Dart, however, I cannot find a way to do something similar with stdin.readLineSync();, it simply outputs:
_
Is there a simple way for a new Dart user to accomplish this? Thank you for your time.
This might do what you want:
import 'dart:io';
main() {
stdout.write('>> ');
var result = stdin.readLineSync();
print(result);
}
write does not automatically add a newline.
A simpler way is to use the DCli package and its ask function:
var response = ask('>>');
print(response);
The ask function provides a number of other options that help capturing data from the cli such as the functions 'confirm' and 'menu'.
https://onepub.dev/packages/dcli

Is there a way to print a console message with Flutter?

I'm debugging an app, but I need to know some values in the fly, I was wondering if there's a way to print a message in console like console.log using Javascript.
I appreciate the help.
print() is probably what you are looking for. Here's some more info on debugging in flutter.
You can use
print()
function or
debugPrint()
The debugPrint() function can print large outputs.
There are more helpful methods in import 'dart:developer' library and one of them is log().
example:
int i = 5;
log("Index number is: $i");
//output
[log] Index number is: 5
void log(String message, {DateTime time, int sequenceNumber, int level
= 0, String name = '', Zone zone, Object error, StackTrace stackTrace})
Emit a log event.
This function was designed to map closely to the logging information
collected by package:logging.
[message] is the log message
[time] (optional) is the timestamp
[sequenceNumber] (optional) is a monotonically increasing sequence number
[level] (optional) is the severity level (a value between 0 and 2000); see the package:logging Level class for an overview of the
possible values
[name] (optional) is the name of the source of the log message
[zone] (optional) the zone where the log was emitted
[error] (optional) an error object associated with this log event
[stackTrace] (optional) a stack trace associated with this log event
Read more.:
print() is from dart:core and its implementation:
/// Prints a string representation of the object to the console.
void print(Object object) {
String line = "$object";
if (printToZone == null) {
printToConsole(line);
} else {
printToZone(line);
}
}
debugPrint():
/// Prints a message to the console, which you can access using the "flutter"
/// tool's "logs" command ("flutter logs").
///
/// If a wrapWidth is provided, each line of the message is word-wrapped to that
/// width. (Lines may be separated by newline characters, as in '\n'.)
///
/// By default, this function very crudely attempts to throttle the rate at
/// which messages are sent to avoid data loss on Android. This means that
/// interleaving calls to this function (directly or indirectly via, e.g.,
/// [debugDumpRenderTree] or [debugDumpApp]) and to the Dart [print] method can
/// result in out-of-order messages in the logs
// read more here: https://api.flutter.dev/flutter/foundation/debugPrint.html
DebugPrintCallback debugPrint = debugPrintThrottled;
/// Alternative implementation of [debugPrint] that does not throttle.
/// Used by tests.
debugPrintSynchronously(String message, { int wrapWidth })
/// Implementation of [debugPrint] that throttles messages. This avoids dropping
/// messages on platforms that rate-limit their logging (for example, Android).
void debugPrintThrottled(String message, { int wrapWidth })
Read more.
Note that only the print() is taking any type and print to the console. debugPrint() and log() only take String. So, you have to add .toString() or use string interpolation like I shown in provided example snippet.
I tend to do something similar to this
Foo foo;
try{
foo = _someMethod(); //some method that returns a new object
} catch (e) {
print('_someMethod: Foo Error ${foo.id} Error:{e.toString()}'); /*my custom error print message. You don't need brackets if you are printing a string variable.*/
}
Use debug print to avoid logging in production application.
debugPrint("Message");
You can also disable or change debug print implementation in main.dart or any other file like this:
debugPrint = (String message, {int wrapWidth})
{
debugPrintThrottled(message);//Or another other custom code
};
print, debugPrint and others have got some word limit restrictions, if you have something long to print on console, you can:
Create this method:
void printWrapped(String text) {
final pattern = RegExp('.{1,800}'); // 800 is the size of each chunk
pattern.allMatches(text).forEach((match) => print(match.group(0)));
}
Usage:
printWrapped("Your very long string ...");
Source
One more answer for Concatenate with String:
// Declaration
int number = 10;
//Button Action
RaisedButton(
child: Text("Subtract Me"),
onPressed: () {
number = number - 1;
print('You have got $number as result');
print('Before Value is ${number - 1} and After value is ${number + 1}');
},
),
//Output:
flutter: You have got 9 as result
flutter: Before Value is 8 and After value is 10
debugPrint()
Might as well use rather than print() as it attempts to reduce log line drop or being out of order on Android kernel
Refs:
Logging in Flutter
I think this might help you, because, I was also got stuck in many ways of knowing the output of my code in the dart file, hence I got the solution by following the steps, shown in the video.
https://www.youtube.com/watch?v=hhP1tE-IHos
here I have shown an instance of how it works after following the video.
check the left side column where it shows about the value which profile variable carry i.e., null
you can simply use print('whatever you want to print') same as console.log() in javascript.
for more info you can check here.
Note that the print() and log() options both add their own labels at the start of the line, and apply additional formatting that can cause long lines to be truncated. In the case of a dart:io app, you can bypass this interception and mangling entirely by going directly to stdout/stderr, etc. as in stdout.write(), stdout.writeln(), etc. Likewise if you are looking to log explicitly to one or the other. I ran into this issue when adding CLI args to a flutter application.
I use something like this. The print() function can print data up to some limit. So I use this log.
import 'dart:developer';
debugLog({String tag = '', required dynamic value}) {
log("TAG $tag : ${value.toString()}");
}

Using Futures to load config.json in Flutter

Being new to Dart/Flutter I am using this snippet to try and load a config.json file that I have stored in my assets folder. In trying to read this file, I am using models on the Dart language Futures documentation and in the Flutter docs on reading local text files:
import 'dart:async' show Future;
import 'package:flutter/services.dart' show rootBundle;
import 'dart:convert';
Future<List> loadAsset() async {
String raw = await rootBundle.loadString('assets/config.json');
List configData = json.decode(raw);
return configData;
}
Then, inside my class, I try to load the config into a List, like this:
Future<List> configData = loadAsset();
print(configData.toString());
// prints out: Instance of 'Future<List<dynamic>>'
The result of all this seems to work. Yet I can find no way of using the data I have loaded. Any effort to access elements in the List, e.g. configData[0] results in an error:
The following _CompileTimeError was thrown building
HomePage(dirty, state: HomePageState#b1af8):
'package:myapp/pages/home_page.dart': error:
line 64 pos 19: lib/pages/home_page.dart:64:19:
Error: The method '[]' isn't defined for the class
'dart.async::Future<dart.core::List<dynamic>>'.
Try correcting the name to the name of an existing method,
or defining a method named '[]'.
I would like to convert the configData Future into a normal object that I can read and pass around my app. I am able to do something very similar, and to get it to work inside a widget's build method, using a FutureBuilder and the DefaultAssetBundle thus...
DefaultAssetBundle
.of(context)
.loadString('assets/config.json')
...but I don't want the overhead of reloading the data inside all the widgets that need it. I would like to load inside a separate Dart package and have it available as a global configuration across all my app. Any pointers would be appreciated.
I have tried the suggestion by Rémi Rousselet:
List configData = await loadAsset();
print(configData[0]);
In this case, I get a compiler error:
compiler message: lib/pages/home_page.dart:55:21: Error: Getter not found: 'await'.
compiler message: List configData = await loadAsset();
compiler message: ^^^^^
You can't do configData[0] as configData is not a List but a Future.
Instead, await the future to have access to the List inside
List configData = await loadAsset();
print(configData[0]);
You can only use await INSIDE async methods.
If you want to you your assets in entire application you want to load the asset in the main method similar like this.
void main() async {
StorageUtils.localStorage = await SharedPreferences.getInstance();
}
Now you can use localStorage synchronously in entire application and you don't need to deal with another asynchronous calls or load it again.
Different example, same principle.

Conditional imports / code for Dart packages

Is there any way to conditionally import libraries / code based on environment flags or target platforms in Dart? I'm trying to switch out between dart:io's ZLibDecoder / ZLibEncoder classes and zlib.js based on the target platform.
There is an article that describes how to create a unified interface, but I'm unable to visualize that technique not creating duplicate code and redundant tests to test that duplicate code. game_loop employs this technique, but uses separate classes (GameLoopHtml and GameLoopIsolate) that don't seem to share anything.
My code looks a bit like this:
class Parser {
Layer parse(String data) {
List<int> rawBytes = /* ... */;
/* stuff you don't care about */
return new Layer(_inflateBytes(rawBytes));
}
String _inflateBytes(List<int> bytes) {
// Uses ZLibEncoder on dartvm, zlib.js in browser
}
}
I'd like to avoid duplicating code by having two separate classes -- ParserHtml and ParserServer -- that implement everything identically except for _inflateBytes.
EDIT: concrete example here: https://github.com/radicaled/citadel/blob/master/lib/tilemap/parser.dart. It's a TMX (Tile Map XML) parser.
You could use mirrors (reflection) to solve this problem. The pub package path is using reflection to access dart:io on the standalone VM or dart:html in the browser.
The source is located here. The good thing is, that they use #MirrorsUsed, so only the required classes are included for the mirrors api. In my opinion the code is documented very good, it should be easy to adopt the solution for your code.
Start at the getters _io and _html (stating at line 72), they show that you can load a library without that they are available on your type of the VM. Loading just returns false if the library it isn't available.
/// If we're running in the server-side Dart VM, this will return a
/// [LibraryMirror] that gives access to the `dart:io` library.
///
/// If `dart:io` is not available, this returns null.
LibraryMirror get _io => currentMirrorSystem().libraries[Uri.parse('dart:io')];
// TODO(nweiz): when issue 6490 or 6943 are fixed, make this work under dart2js.
/// If we're running in Dartium, this will return a [LibraryMirror] that gives
/// access to the `dart:html` library.
///
/// If `dart:html` is not available, this returns null.
LibraryMirror get _html =>
currentMirrorSystem().libraries[Uri.parse('dart:html')];
Later you can use mirrors to invoke methods or getters. See the getter current (starting at line 86) for an example implementation.
/// Gets the path to the current working directory.
///
/// In the browser, this means the current URL. When using dart2js, this
/// currently returns `.` due to technical constraints. In the future, it will
/// return the current URL.
String get current {
if (_io != null) {
return _io.classes[#Directory].getField(#current).reflectee.path;
} else if (_html != null) {
return _html.getField(#window).reflectee.location.href;
} else {
return '.';
}
}
As you see in the comments, this only works in the Dart VM at the moment. After issue 6490 is solved, it should work in Dart2Js, too. This may means that this solution isn't applicable for you at the moment, but would be a solution later.
The issue 6943 could also be helpful, but describes another solution that is not implemented yet.
Conditional imports are possible based on the presence of dart:html or dart:io, see for example the import statements of resource_loader.dart in package:resource.
I'm not yet sure how to do an import conditional on being on the Flutter platform.

Resources