Export two library which have same class name - dart

I met an error when exporting two libraries. And these libraries have exactly same class name.
File: A.dart
library chrome.A;
class MyClass {
...
}
File: B.dart
library chrome.B;
class MyClass {
..
}
File: C.dart
library chrome_app;
export 'A.dart';
export 'B.dart'; // HERE!! error message for the element 'MyClass' which is defined in the libraries 'A.dart' and 'B.dart'
Is this the intended result?
I think A.dart and B.dart has their own namespace so that there should be no error.

A library name isn't a namespace. Dart doesn't have namespaces.
What you can do in Dart is to specify a prefix for an import.
You have to import those libraries separately if you want to use them in the same library instead of just one import with import 'C.dart;'
import 'A.dart' as a;
import 'B.dart' as b;
var m = a.MyClass();
var n = b.MyClass();
If you just want to avoid the conflict and don't need both classes exported you can.
library chrome_app;
export 'A.dart';
export 'B.dart' hide MyClass;
// or
export 'B.dart' show MyOtherClass, AnotherOne; // define explicitly which classes to export and omit MyClass

Related

In Dart, Is it not possible to inherit packages?

import "dart:html";
class ParentClass {
}
import "ParentClass";
class ChildClass extends ParentClass {
int main() {
Element e = querySelector()
}
}
Element & querySelector in ChildClass display as issues (Undefined Element & querySelector)
Is it not possible to import packages from ParentClass?
An import's scope is only the importing library.
If you import dart:html in the ParentClass library file and import the ParentClass library in another file, then the other file does not see the dart:html declarations.
There is two ways to handle that:
Preferably, just import dart:html in the other library too.
Export dart:html from the ParentClass library: add export "dart:html"; next to import "dart:html";. That way the declarations of dart:html will be available to any library importing ParentClass.

Dart Can't get logging statements to compile

I'm trying to learn how to implement logging using the examples/tutorial in:
http://blog.dartwatch.com/2013/05/campaign-to-use-real-logging-instead-of.html#comment-form
But having imported the libraries this line in main will not compile because the class 'PrintHandler' is not recognized and Google has not been a help in this case. My server application consists of a main and three classes. I'm new at Dart. Below I've extracted the logging code that I added.
In what library is 'PrintHandler'? Is this a class I need to write?
library server;
import 'package:logging_handlers/logging_handlers_shared.dart';
import 'package:logging/logging.dart';
final _serverLogger = new Logger("server"); // top level logger
void main() {
Logger.root.onRecord.listen(new PrintHandler()); // default PrintHandler
_serverLogger.fine("Server created");
}
class A {
}
class B {
}
class C {
}
It looks like the class was changed to LogPrintHandler but the tutorial and documentation were not updated.

Dart library visibility

My Dart app has the following structure:
myapp/
pubspec.yaml
pubspec.lock
asset/
...
web/
logging/
Logger.dart
LogLevel.dart
...other packages
Where the 2 shown Dart files are:
LogLevel.dart:
library logging;
class LogLevel {
static const TRACE = const LogLevel._(0);
static const INFO = const LogLevel._(1);
static const ERROR = const LogLevel._(2);
static get values => [TRACE, INFO, ERROR];
final int value;
const LogLevel._(this.value);
}
Logger.dart:
library logging; // <== compiler error!?!
import "package:logging/LogLevel.dart";
class Logger {
// ...
}
I figured since I put the two classes into a logging library/package together, that they would be visible to one another. But that's not the case! Instead on the import statement I get the following compiler error:
Target of URI does not exist: 'package:logging/LogLevel.dart'
What's going on here? How should I be packaging/library-ing my types differently so that they'll be visible to one another?
You can import them through their relative path without referring to the package:
import 'LogLevel.dart';
If you do want to import them as packages, they need to be under the lib folder.

What is the difference between "show" and "as" in an import statement?

What is the difference between show and as in an import statement?
For example, what's the difference between
import 'dart:convert' show JSON;
and
import 'package:google_maps/google_maps.dart' as GoogleMap;
When do I use show and when should I use as?
If I switch to show GoogleMap all references to GoogleMap (e.g. GoogleMap.LatLng) objects are reported as undefined.
as and show are two different concepts.
With as you are giving the imported library a name. It's usually done to prevent a library from polluting your namespace if it has a lot of global functions. If you use as you can access all functions and classes of said library by accessing them the way you did in your example: GoogleMap.LatLng.
With show (and hide) you can pick specific classes you want to be visible in your application. For your example it would be:
import 'package:google_maps/google_maps.dart' show LatLng;
With this you would be able to access LatLng but nothing else from that library. The opposite of this is:
import 'package:google_maps/google_maps.dart' hide LatLng;
With this you would be able to access everything from that library except for LatLng.
If you want to use multiple classes with the same name you'd need to use as. You also can combine both approaches:
import 'package:google_maps/google_maps.dart' as GoogleMap show LatLng;
show case:
import 'dart:async' show Stream;
This way you only import Stream class from dart:async, so if you try to use another class from dart:async other than Stream it will throw an error.
void main() {
List data = [1, 2, 3];
Stream stream = new Stream.fromIterable(data); // doable
StreamController controller = new StreamController(); // not doable
// because you only show Stream
}
as case:
import 'dart:async' as async;
This way you import all class from dart:async and namespaced it with async keyword.
void main() {
async.StreamController controller = new async.StreamController(); // doable
List data = [1, 2, 3];
Stream stream = new Stream.fromIterable(data); // not doable
// because you namespaced it with 'async'
}
as is usually used when there are conflicting classes in your imported library, for example if you have a library 'my_library.dart' that contains a class named Stream and you also want to use Stream class from dart:async and then:
import 'dart:async';
import 'my_library.dart';
void main() {
Stream stream = new Stream.fromIterable([1, 2]);
}
This way, we don't know whether this Stream class is from async library or your own library. We have to use as :
import 'dart:async';
import 'my_library.dart' as myLib;
void main() {
Stream stream = new Stream.fromIterable([1, 2]); // from async
myLib.Stream myCustomStream = new myLib.Stream(); // from your library
}
For show, I guess this is used when we know we only need a specific class. Also can be used when there are conflicting classes in your imported library. Let's say in your own library you have a class named CustomStream and Stream and you also want to use dart:async, but in this case you only need CustomStream from your own library.
import 'dart:async';
import 'my_library.dart';
void main() {
Stream stream = new Stream.fromIterable([1, 2]); // not doable
// we don't know whether Stream
// is from async lib ir your own
CustomStream customStream = new CustomStream();// doable
}
Some workaround:
import 'dart:async';
import 'my_library.dart' show CustomStream;
void main() {
Stream stream = new Stream.fromIterable([1, 2]); // doable, since we only import Stream
// async lib
CustomStream customStream = new CustomStream();// doable
}
as and show keywords used with library import statement. These two keywords are optional with import keyword, But using these keywords you can provide convenience and additional information about your library importing.
show
show give restrictions to access only specific class of that library.
import 'dart:convert' show JSON;
Above dart:convert library contains more than 5 types of converters. (ascii,Base64,Latin1,Utf8 & json are some of them).
But with using show keyword you will give your application source file to access only that JSON converter class only.
warning !! :- if you try to access any other converters like ascii, Base64 or Latin1, you will get an exception.
Because using show keyword you give an restriction for only access Json class in that library api.
So if your source file want to access all the class in that library, you cannot define show keyword for that library importing.
as
Provide additional namespace for library members.
This as keyword is mostly used when a library that contains lot of global functions.
You will access static members of a library by Using the class name and . (dot operator).
eg:- ClassName.staticFun()
And also you will access instance methods and variables by using object name and . (dot operator) eg:- obj.instanceFunc()
And also library source file can have global functions. and we will access them by their name without any parental membership. eg:- func()
So when we access global functions of a different library inside our source file, we didnt have a way to seperatly identified that global function as seperate function of a different library.
But using as keyword, we can add namespace before accessing global functions of that library.
See below example to understanding real benefit of as keyword. 👇
import 'package:http/http.dart' as http;
http library contains lot of global functions. Below shows list of global functions in http library.
Accessing above http library global functions without http namespace.( import 'package:http/http.dart'; )
eg:-
1. get("url")
2. post("url")
Accessing above http library global functions with http namespace. ( import 'package:http/http.dart'as http; )
eg:-
1. http.get("url")
2. http.post("url")
So using as keyword , makes it easy to identify global functions of a different library separated from our source files' global functions.
I prefer the dart document, it's described in Libraries and visibility section.
import as: Specifying a library prefix, for example when import two libraries which has the same function name, then we can give them a prefix to specify the library.
import show: This is used to import part of the library, show only import one name of the library.
import hide: This is another one which is the opposite of the show, hide import all names except the name specified in the hide.

Dart 2 libraries in one lib folder causing type 'X' is not a subtype of type 'X'

I have a following problem:
In my application, I have web and lib folders.
Lib folder is supposed to contain utility libraries.
Example:
lib/my_lib.dart
library my_lib;
part 'src/person.dart';
lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
In my_lib1, I want to use classes defined in my_lib
the classes are as follows:
lib/src/person.dart
part of my_lib;
class Person {
}
lib/src/other.dart
part of my_lib1;
class Other {
Person p;
Other(this.p) {
print(p);
}
}
Now, in web/testpackage.dart
import 'package:TestPackage/my_lib.dart';
import 'package:TestPackage/my_lib1.dart';
void main() {
Person p = new Person();
Other o = new Other(p);
}
Fails with:
Exception: type 'Person' is not a subtype of type 'Person' of 'p'.
Other.Other (package:testpackage/src/other.dart:7:14)
How should I structure my project to prevent that?
My libraries are local to the app, and I don't really want to develop them separately for my toy project.
Problem in that the your library my_lib is a publiclibrary and anyone (and you, of course) can use it elsewhere outside of lib directory.
In this case it must be imported (becuase it's a public library) always as the package library.
To solve this this problem you must change your source code.
From this lib/my_lib1.dart
library my_lib1;
import 'my_lib.dart';
part 'src/other.dart';
To this lib/my_lib1.dart
library my_lib1;
import 'package:TestPackage/my_lib.dart';
part 'src/other.dart';

Resources