how can I use component only in dev? - dart

I have some translation components that I would like to use only in the development environment. The idea is that the component does not get compiled when the project builds.
How can I achieve that in AngularDart 5?

Depending on how you'd like your component to be loaded/not loaded, there are different strategies you can take. My preferred one usually is to have two entry-points for your application, i.e. web/main.dart, and web/main.dev.dart, and have the latter be the only one that imports/uses/loads the component in question.
For example, you could have the following definition in lib/translation.dart:
void Function() loadTranslationComponent = () {};
And in web/main.dev.dart:
import 'package:name/translation.dart';
void main() {
loadTranslationComponent = () {
// Code to initialize and use only in development mode.
};
}

Related

React Native IOS Bridge Native View - proper way to call Native Method from JS side

I want to discuss the options i have come across for calling a native method from a IOS ViewManager/View in JS side without using properties but direct method calls.
Option A:
implementing a method in the ViewManager which searches for the correct view and calls the given method in the view, like this:
func callMethodViaManager(_ node:NSNumber) {
DispatchQueue.main.async {
let myView = self.bridge.uiManager.view(forReactTag: node) as! MyView
myView.myMethod()
}
}
and then in the JS side implement a handler like this:
const handleSomething = (e) => {
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(ref.current),
UIManager.SwiftComponent.Commands.callMethodViaManager,
[])
};
This is just a short summary of the relevant parts, the process in full can be seen in full detail maybe just a bit old but with some adjustments one can get it to work also with functional components:
https://medium.com/#jjdanek/react-native-calling-class-methods-on-native-swift-views-521faf44f3dc
Option B:
For this option let's go with the best scenario which is that one can get all the necessary data, setup, etc on the ViewManager ready via delegates for example or some other pattern or Swift sugar.
Calling the Native methods in the ViewManager from the JS side directly with the use of NativeModules, like this:
const handleSomething = (e) => {
NativeModules.MyViewManager.myMethod()
};
I could not find much about this option in correlation to a Native View being bridged, this way of doing it is used for Native Module bridging explicitly. The only things i could find where:
React Native UI Component Method
or guides like these one:
https://teabreak.e-spres-oh.com/swift-in-react-native-the-ultimate-guide-part-1-modules-9bb8d054db03#4377
I have tried both methods and at first glance they seem to work both.
So my questions are:
Why is Option A the better solution/option and the one which is recommended or most used?
What is wrong or can go wrong with Option B?
Is there anything else to take into consideration?
Is there a better way which is not trough properties?
Option B is more flexible.
If you use Option A, then you can't pass Promise and Callback parameter to the native side.
It seems possible in iOS But not in Android.
This is a related issue.
React Native bridge API is all confusing
There is no guide about how to call the native UI method with Promise or Callback.
There is a example about how to pass Promise to native side with calling native UI instance method.
SketchView... is just my example module name.
class SketchViewModule(reactContext: ReactApplicationContext) : ReactContextBaseJavaModule(reactContext) {
override fun getName() = "SketchViewModule"
private fun runCommandWithPromise(
viewId: Int, promise: Promise, handler: (view: SketchView) -> Unit
) {
reactApplicationContext.getNativeModule(UIManagerModule::class.java)?.let { uiManager ->
uiManager.addUIBlock {
(it.resolveView(viewId) as? SketchView)?.let { view ->
handler(view)
} ?: run {
promise.safeReject("[runCommandWithPromise] Cannot find View with UIManager")
}
}
}
}
...

Using InjectorFactory for routerProviders or routerProvidersHash can be automated?

I'm bootstrap angular with runApp and the namend Parameter "createInjector" to define the routerStrategy "routerProviders" or "routerProvidersHash".
Is there any way to automate this definition like i wish to do this in my first line? For local development i wish to use "routerProvidersHash" and for live environment is wanna use the "routerProvider".
const List<Provider<Object>> routerStrategy = Environment.isLive() ? routerProviders : routerProvidersHash;
#GenerateInjector([
routerStrategy,
ClassProvider(Client, useClass: BrowserClient),
])
final InjectorFactory injector = self.injector$Injector;
void main() {
runApp(ng.AppComponentNgFactory, createInjector: injector);
}
The problem is, that this value need to be a const, but then i can not create the constant like this.
I have no idea to make this more flexible :(
It is const very much on purpose as if it is dynamic like you suggest then it can't be optimized.
What I think you can do is have two injectors one for devel, and one for prod and decide which one to use when you call runApp.

Vaadin 7 how to check if scrollbar is visible or not

How to check in Vaadin 7 if scrollbar is visible or not for a certain component, for example for Panel
Any implementation of AbstractClientConnector can be extended with AbstractExtension: https://vaadin.com/api/com/vaadin/server/AbstractExtension.html
An extension is a possible way to extend the functionality of your component: https://vaadin.com/docs/-/part/framework/gwt/gwt-extension.html
Adding features to existing components by extending them by inheritance creates a problem when you want to combine such features. For example, one add-on could add spell-check to a TextField, while another could add client-side validation. Combining such add-on features would be difficult if not impossible. You might also want to add a feature to several or even to all components, but extending all of them by inheritance is not really an option. Vaadin includes a component plug-in mechanism for these purposes. Such plug-ins are simply called extensions.
In the client-side extension implementation you can write your custom GWT code like following (pseudo code):
#Override
protected void extend(ServerConnector target) {
// Get the extended widget
final Widget widget = ((ComponentConnector) target).getWidget();
// register RPCs
YourServerRpcImplementation serverRpc = getRpcProxy(YourServerRpcImplementation.class); // client to server
registerRpc(YourClientRpcImplementation.class, this); // server to client, unused in this example
// add listener and update server state
Window.addResizeHandler(new ResizeHandler() {
#Override
public void onResize(ResizeEvent event) {
boolean scrollbarVisible = widget.getElement().getScrollHeight() > widget.getElement().getClientHeight();
serverRpc.yourEventMethod(scrollbarVisible);
}
});
}
Passing events between server and client: https://vaadin.com/docs/-/part/framework/gwt/gwt-rpc.html

How do you interact with js from dart?

No, this isn't the same as the other question of the same name.
There are seemingly identical packages which seem to do this, but with different apis.
http://dart-lang.github.io/js-interop/docs/js.html
https://api.dartlang.org/docs/channels/stable/latest/dart_js.html
Why are there two?
Which one are we supposed to use?
The interop one looks newer and has a better api, but doesn't actually work. According to the documentation, you should be able to convert this javascript:
var stage = new PIXI.Stage(0xFFFFFF);;
renderer = PIXI.autoDetectRenderer(800, 600);
document.body.appendChild(renderer.view);
Into:
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
document.body.append(renderer.view);
But that errors when you try to compile it:
dart2js
Error occured:/Users/doug/megac/client/public/dart/index.dart:7:27:
Warning: No member named 'PIXI' in class 'Proxy'.
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
^^^^^^^^^^^^^^^
So... js:dart? Is that what you're supposed to use?
Edit: Incidentally, for anyone who stumbles into this, there is also an open bug http://code.google.com/p/dart/issues/detail?id=15795&thanks=15795&ts=1388068177 regarding how minified dart-js interop bridge operations don't currently work. The original issue was reported in May 2013, and there's been no action on it since then, so don't hold your breath.
Js interop started with package:js. It was built with with window.postMessage.
Later dart:js has been added to provide better performance and reduce the size of the compiled js file. Basically the goal were :
removing scopes and lifecycle manual handling
avoiding noSuchMethod to keep compilation size as low as possible
renaming objects to make the api more understandable
Once dart:js has been ready, package:js has been rewrite to use dart:js under the cover.
package:js provides a simpler Api that comes at the cost of an increase of the js size (because package:js uses dart:mirrors and noSuchMethod).
Here is the same thing done with package:js and dart:js :
import 'package:js/js.dart' as js;
main() {
var pixi = new js.Proxy(js.context.PIXI.Stage, 0xffffff);
var renderer = js.context.PIXI.autoDetectRenderer(400, 400);
document.body.append(renderer.view);
}
import 'dart:js' as js;
main() {
var pixi = new js.JsObject(js.context['PIXI']['Stage'], [0xffffff]);
var renderer = js.context['PIXI'].callMethod('autoDetectRenderer', [400, 400]);
document.body.append(renderer['view']);
}

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