I'm new to dart, and following the tutorial provided on the Dart for the web page.
It all makes sense - apart from one piece of sytax:
final InjectorFactory injector = self.injector$Injector;
Here's the full code from the tutorial:
import 'main.template.dart' as self;
const useHashLS = false;
#GenerateInjector([
routerProvidersHash,
ClassProvider(Client, useClass: InMemoryDataService),
// Using a real back end?
// Import 'package:http/browser_client.dart' and change the
above to:
// ClassProvider(Client, useClass: BrowserClient),
])
final InjectorFactory injector = self.injector$Injector;
void main() {
runApp(ng.AppComponentNgFactory, createInjector: injector);
}
I'm a confused by the apparent .method$Class syntax. Can anyone explain to me what this means/what it's doing?
It's also underlined in Webstorm with the message The getter 'injector$Injector' isn't defined for the class 'self'. Regardless, it runs fine and works as expected.
Thanks in advance!
$ in an identifier has no special meaning. It's by convention often used for names in generated code.
Angular also uses code generation and the code will only become available after code generation was executed for example by webdev serve or webdev build.
I don't know the current state but the code might still be generated in a directory that is not analyzed by the DartAnalyzler and you might always see the error even wen the app can be run without problems.
Related
I have a single file Dart program - let's say main.dart. I'm trying to provide some compile time environment values to it using --dart-define=env=env_value but in the Dart program, I'm always getting the default values.
This is what my Dart program looks like
void main() {
const myValue = const String.fromEnvironment("MY_VALUE", defaultValue: "DEFAULT");
print('My value: $myValue'); // Always prints "DEFAULT"
}
This is the command I'm using to run my program
dart main.dart --dart-define=MY_VALUE=SOME_VALUE
Now, when I include the exact same code from above in a Flutter app and run it with the below command, everything seems to work as expecetd but for some reason the above program always prints DEFAULT as the output on console.
flutter run --dart-define=MY_VALUE=SOME_VALUE
Is there something I'm missing when it comes to providing these values in a Dart program? I'm running macOS if that helps in any way.
If you type:
dart --help --verbose
It will give you the list of supported flags.
Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]
Executes the Dart script <dart-script-file> with the given list of <script-arguments>.
Supported options:
...
--define=<key>=<value> or -D<key>=<value>
Define an environment declaration. To specify multiple declarations,
use multiple instances of this option.
...
So it appears that the flag you want is --define or -D, rather than --dart-define. Also note that this is considered a "vm-flag" and must come before the file name in order to work.
Therefore the following command should work:
dart --define=MY_VALUE=SOME_VALUE main.dart
I try to write some custom lint rules. To achieve this, I used the analyzer_plugin package and I set up my project as it should be. Here is a simplified excerpt of the main class :
class LintAnalyzerPlugin extends ServerPlugin {
#override
Future<void> analyzeFile({required AnalysisContext analysisContext, required String path}) async {
channel.sendNotification(
AnalysisErrorsParams(path, [getAnalysisError(path)]).toNotification(),
);
}
}
channel.sendNotification is called but no message is displayed into VS Code Problems panel.
After some investigation, I found out that the JSON generated for the sent notification use Dart server Legacy protocol. But the Dart analyzer server run by Dart Code extension wait for LSP (Microsoft Language Server Protocol).
Fortunately the extension offers a setting to start the server with the Legacy protocol:
"dart.useLegacyAnalyzerProtocol": true
And now the VS Code Problems panel populates sent notifications.
Unfortunately Dart Code extension advises to use LSP because the Legacy protocol will eventually be removed some day.
Is it possible to generate LSP? Or did I miss something?
If anyone has any suggestions, I'm all ears.
I'm new to the Dart functions framework. My goal is to use this package to create several functions and deploy them to Cloud Run (in combination with Firebase, but I guess that's irrelevant to this question).
I've run the quick starts and I've read all of the contents in the docs.
The quick start mentions just one function at a time (e.g. Hello World, Cloud Events, etc..), like this:
import 'package:functions_framework/functions_framework.dart';
import 'package:shelf/shelf.dart';
#CloudFunction()
Response function(Request request) {
return Response.ok('Hello, World!');
}
But as you can see in the quickstarts only one function is handled in a project at a time. How about me wanting to deploy several functions? Should I:
Write several functions in the same project / file, so that the function framework compiles the 'server.dart` by itself
OR
Create a different functions_framework for each function?
Let me be more specific. Should I do the following (option 1 - which makes more sense to me):
import 'dart:math';
import 'package:functions_framework/functions_framework.dart';
import 'package:shelf/shelf.dart';
#CloudFunction()
Response function(Request request) {
return Response.ok('Hello, World!');
}
#CloudFunction()
Response function2(Request request) {
if (Random().nextBool()) {
return Response.ok('Hello, World!');
} else {
return Response.internalServerError();
}
}
Or should I build a different folder by running a build_runner for each function I need in my project?
Is there a difference and/or a best practice?
Thanks in advance.
EDIT. This question is related to the deployment on Cloud Run itself, and not just testing on my own PC. To test my own functions I did the following:
Run dart run build_runner build, so that it updates the server.dart file correctly (I can see that the framework does a lot behind the scenes and that the _nameToFunctionTarget is basically a router);
Run the server in two different terminals, like this: dart run bin/server.dart --port MYPORT --target MYFUNCTION (where MYPORT and MYFUNCTION are either 8080/8081 or function/function2 respectively).
I guess I'm just confused on how to correctly manage this framework once deployed on Cloud Run.
EDIT 2. I just gave up using Dart as a Serverless language or even a Backend language. There's just too much jargon even for the basic things. Any backend framework is either dead, or maintained by one single enthusiast guy (props to him!). This language has not yet received enough love from the Google Team / the community and at this moment in time is basically not possible to go fullstack on just Dart. It's a dream, but it can't be realized now. Furthermore, Dart hardly lacks a proper SDKs to use Firestore, etc., so Firebase isn't an option. I find it easier to just learn NodeJS and exploit the Firebase support for Firebase Functions written in NodeJS, and I'll wait for more support in there in the future, if there ever will be.
The documentation is a bit sparse right now (and I'm new to it also! I couldn't find any good examples, so here goes...)
You can only have a single function that is served. It should be
named 'function' (the type and name can be overriden, see the
cloudevent example dartfn generate cloudevent)
You 'could' have many of these deployed so that each does a specific thing, such as processing cloudevents above, but most people
want something more REST-like (see next)
You need to attach a Router() so that you can have the single entry point (function) handled by specific logic in your code.
Example for Rest
add to pubspec.yaml (in dependencies:) shelf_router: ^1.1.2
delegate the #CloudFunction to use the Router()
functions.dart
import 'package:functions_framework/functions_framework.dart';
import 'package:shelf/shelf.dart';
import 'package:shelf_router/shelf_router.dart';
Router app = Router()
..get('/health', (Request request) {
return Response.ok('healthy');
})
..get('/user/<user>', (Request request, String user) {
// fetch the user... (probably return as json)
return Response.ok('hello $user');
})
..post('/user', (Request request) {
// convert request body to json and persist... (probably return as json)
return Response.ok('saved the user');
});
#CloudFunction()
Future<Response> function(Request request) => app.call(request);
Dart is suppose to be pragmatic, intuitive, etc.
I wonder Why top-level main() does not set exitcode if int is returned?
I know, you can set it via dart:io.exitCode= or use dart:io.exit().
The question is why language designers decided to drop such popular convention?
#!/path/to/dart --checked
int main() {
int myExitCode = 5;
return myExitCode;
}
It returns 0 (as described in documentation), but in command-line world it's just silly.
It does not even warn you (compiler checked mode, dartanalyzer). Script just silently return 0. Is there any rationale behind it?
UPDATE:
proposal bug: https://code.google.com/p/dart/issues/detail?id=21639
The main() method in Dart always returns void, even if you specify otherwise. See The main() function As mentioned in the answer from John Evans, you must use the exit function if you want to return a value. This is because the Dart VM runs in both CLI and in a browser. It makes no sense in terms of the browser to provide a return value from main(). Thus the functionality is limited to the dart:io library which will only run in the CLI version of the dart VM.
My understanding for this is that while main() may finish executing, you might have other asynchronous work going on that hasn't completed yet. You can use exit from the dart:io lib to return a exit code immediately.
import 'dart:io';
main(){
exit(42);
}
More info from the API docs about exit: https://api.dartlang.org/apidocs/channels/stable/dartdoc-viewer/dart:io#id_exit
Possible answer would be that returning value from main() will not make sense in browser (as Matt B pointed out, +1), so dart does not let it at all.
But this is incoherent, since getting list of commandline arguments main(List<String> args) does not make sense in a browser environment either, and dart languages supports main(List<String> args).
On the other hand, support for main-return-sets-exitCode feature would tight heart of dart
(how top-level main() is treated) to dart:io which is not available in browsers.
However, I personally don't think it wouldn't be that bad as having such wired and unexpected behavior as shown in the question's code.
I'm looking for a way to generate a warning anywhere in my code (top level, class, functions). As I'm typically having a 0 warning policy, this enables me to see where I make a change I need to revert before commit
For example in Java, i could do this:
private int warning_revert_to_false;
boolean DEBUG = true;
and it will generate a warning (according to my settings).
Using jslint/jshint that's easy (mixed tab/space for example), in C/C++ i can use pragma...
Basically I want the code to still compile and run and so far in Dart, I could not find a simple solution and I'm sure there is one that I have missed. Thanks!
Add the following library to your program:
library forced;
import 'package:meta/meta.dart';
class Forced {
#deprecated
static void warning() {
}
}
Wherever you want a forced warning you can simply write:
Forced.warning();