stateless react components in scalajs-react - scalajs-react

What is the easiest way to write this ({value}) => <li>{value}</li> stateless react component in scalajs-react ?
I've found the following related links on the net but they do not answer the question:
https://gitter.im/japgolly/scalajs-react?at=557e2a0dc030cae67ed3a4c3
https://github.com/japgolly/scalajs-react/blob/master/core/src/main/scala/japgolly/scalajs/react/ReactComponentB.scala#L41
https://gitter.im/japgolly/scalajs-react?at=561705054e0fa3e55447ba98
http://www.gitterforum.com/discussion/japgolly-scalajs-react?page=269
https://gitter.im/japgolly/scalajs-react?at=57ae33f90fd99f7041367604
This seems to be the closest to an answer:
https://gitter.im/japgolly/scalajs-react?at=575347a19be9c5b637f07a00
case class StatelessProps(name: String)
val stateless = FunctionalComponent((props: StatelessProps) => {
<.span(s"My name is ${props.name}")
})
I am not sure though if this is a stateless react component or not.
Is FunctionalComponent the same as stateless react component ?
OK, it seems that it is : https://gitter.im/japgolly/scalajs-react?at=575329dc9be9c5b637f074e8

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")
}
}
}
}
...

Override UrlResolver

I've been working through the Angular 2 tutorial (in TypeScript) when I got stuck on this part. They now want to separate templates into separate files. That's fine and dandy, but I've got a quirky setup: I'm serving up the files with ASP.NET MVC, and it's refusing to serve up the file from the Views folder. Fair enough: I anticipate needing to serve up Razor (.cshtml) files, so I'm happy to try and hack this out instead of just whitelisting .html.
I've worked with Angular 1 before, and in this situation I used a decorator to modify the $templateRequest service to modify the template URLs into something MVC will accept, and then I set up MVC to serve up the corresponding files. Quite clever work if I do say so myself. So I just need to replicate this in Angular 2, right? That should be easy.
Wrong. So wrong. After some guesswork Googling I found UrlResolver which, after some client-side debugging I confirmed, is the class I want to extend. The documentation even says:
This class can be overridden by the application developer to create custom behavior.
Yes! This is exactly what I want to do. Unfortunately no examples of how to override it have been supplied. I've found this DemoUrlResolver and this MyUrlResolver, but I can't figure out how or if either of them works. I've tried the multiple approaches to supplying my custom provider (see this answer) including the bootstrap and providers (on the module and the app component) approaches all to no avail.
How do I override UrlResolver?
I assume it doesn't matter, but at the moment my extension does nothing but defer to the base class:
class MvcUrlResolver extends UrlResolver {
resolve(baseUrl: string, url: string): string {
return super.resolve(baseUrl, url);
}
}
Interesting question. Since it is part of compiler it makes sense that it would not be instantiated along with other application components, and after some research and analyzing angular's code I found the solution. You need to provide it directly in the call to platformBrowserDynamic(). In this case it will be merged into default compiler options and will be used by injector that instantiates compiler.
import { COMPILER_OPTIONS } from '#angular/core';
class MvcUrlResolver extends UrlResolver {
resolve(baseUrl: string, url: string): string {
let result = super.resolve(baseUrl, url);
console.log('resolving urls: baseUrl = ' + baseUrl + '; url = ' + url + '; result = ' + result);
return result;
}
}
platformBrowserDynamic([{
provide: COMPILER_OPTIONS,
useValue: {providers: [{provide: UrlResolver, useClass: MvcUrlResolver}]},
multi: true
}]).bootstrapModule(AppModule);

Compose exported value with MEF 2

With MEF 1 it was possible to compose an existing object to the container with the ComposeExportedValue(...)-Method (container.ComposeExportedValue...). How can this be done with Microsoft.Composition (MEF 2)? I can't find any Method for this purpose.
I will have a shot at this one. Granted, I am only about a week in on learning MEF 2 myself, after having some limited exposure to MEF 1. So, please take that in consideration with the following answer as it could be completely wrong. Also, I have found documentation very poor and out of date so it has been an uphill battle in every respect thus far.
In my solution, I made use of the ExportDescriptorProvider and extended it as an InstanceExportDescriptorProvider as the following code demonstrates.
(Please note this should be considered proof-of-concept and not final code!)
public class InstanceExportDescriptorProvider : ExportDescriptorProvider
{
readonly object instance;
public InstanceExportDescriptorProvider( object instance )
{
this.instance = instance;
}
public override IEnumerable<ExportDescriptorPromise> GetExportDescriptors( CompositionContract contract, DependencyAccessor descriptorAccessor )
{
if ( contract.ContractType.IsInstanceOfType( instance ) )
{
yield return new ExportDescriptorPromise( contract, contract.ContractType.FullName, true, NoDependencies, dependencies => ExportDescriptor.Create( ( context, operation ) => instance, NoMetadata ) );
}
}
}
Supporting test (using xUnit 2.0 paired with AutoFixture) to show how this would be used is as follows:
[Theory, AutoData]
public void VerifyInstanceExport( Assembly[] assemblies )
{
using ( var container = new ContainerConfiguration()
.WithProvider( new InstanceExportDescriptorProvider( assemblies ) )
.CreateContainer() )
{
var composed = container.GetExport<Assembly[]>();
Assert.Equal( assemblies, composed );
}
}
In my case I want to have access to the assemblies passed into the ContainerConfiguration (not seen/tested in the above example) so that is why I am testing with Assemblies.
Hopefully this will be enough to get you on on your way. Or some way, in any case.
https://mef.codeplex.com/ states that
System.Composition.*_ is a lightweight version of MEF, which has been optimized for static composition scenarios and provides faster compositions.
And as far as I know from my experience System.Composition doesn't support dynamic composition. If you need such capabilities you've got to use standard MEF (System.ComponentModel.Composition.*).

Inject bridge-code in JavaFX WebView before page-load?

I want to load some content or page in a JavaFX WebView and offer a Bridge object to Java so the content of the page can do calls into java.
The basic concept of how to do this is described here: https://blogs.oracle.com/javafx/entry/communicating_between_javascript_and_javafx
Now my question is: When is a good time inject the bridge-object into the WebView so it is available as soon as possible.
One option would be after page load as described here: https://stackoverflow.com/a/17612361/1520422
But is there a way to inject this sooner (before the page content itself is initialized), so the bridge-object is available DURING page-load (and not only after page-load)?
Since no one has answered, I'll tell you how I'm doing it, although it is ugly. This provides the ability for the page to function normally in non-Java environments but receive a Java object in Java environments.
I start by providing an onStatusChanged handler to the WebEngine. It listens for a magic value for window.status. If the magic value is received, the handler installs the Java object. (In my case, it's more complex, because I have some more complex orchestration: I'm executing a script that provides a client-side API for the page and then sets another magic value on window.status to cause the Java object to be sent to an initialization method of the client-side API).
Then in my target page, I have the following code in the first script in the page:
window.status = "MY-MAGIC-VALUE";
window.status = "";
This code is essentially a no-op in a "normal" browser but triggers the initialization when running in the custom JavaFX embedding.
In Java 8, you can trigger event changing from SCHEDULED to RUNNING to inject objects at this time. The objects will present in WebEngine before JavaScript running. Java 7, I see the state machine quite differs in operating, no solution given for Java 7.
webEngine.getLoadWorker().stateProperty().addListener(
new ChangeListener<State>(){
public void changed(ObservableValue<? extends State> ov,
State oldState,
State newState)
{
// System.out.println("old: "+oldState+", new: "+newState);
if(newState == State.RUNNING &&
oldState == State.SCHEDULED){
JSObject window = (JSObject)webEngine.executeScript("window");
window.setMember("foutput", foutput);
}
}
});

Spring .Net Configuration Fluently

I have the need to use Spring .Net in a project and am exploring configuration options. All I can find about config for Spring .Net is config file stuff. Does Spring support configuration in code? I have used Castle and Ninject, and both seem to offer this natively. I have found projects that claim to add support, but I dont want some knock off project that will die in 6 months. I have found references in blogs that seem to indicate Spring supports this but I cant find any documentation!!
Part 2 of this might be would you recommend Spring .Net over Windsor knowing it cant support fluent configuration? I know both are great IoC containers, but I have worked on projects that have massive config files for Spring configuration and I hate it.
No, the current version (1.3) of Spring.NET only supports XML configuration. There has been talk about supporting Code as Configuration in future versions, but this has not yet materialized.
In my opinion, Castle Windsor is far superior to Spring.NET. I can't think of a single feature of Spring.NET that Castle Windsor doesn't have. On the other hand, Castle Windsor has the following features that are not available in Spring.NET:
Code as Configuration
Convention-based configuration
More lifetimes
Custom lifetimes
Object graph decommissioning
Explicit mapping of interfaces/base classes to concrete types
Type-based resolution
Modular configuration (Installers)
Built-in support for Decorators
Typed Factories
There are probably other features I forgot about...
It appears I was a bit too quick on the trigger here, although to my defense, the Spring.NET documentation also states that there's only XML configuration in the current version.
However, it turns out that if for certain contexts, a very primitive API is available that enables you to configure a context without XML. Here's an example:
var context = new GenericApplicationContext();
context.RegisterObjectDefinition("EggYolk",
new RootObjectDefinition(typeof(EggYolk)));
context.RegisterObjectDefinition("OliveOil",
new RootObjectDefinition(typeof(OliveOil)));
context.RegisterObjectDefinition("Mayonnaise",
new RootObjectDefinition(typeof(Mayonnaise),
AutoWiringMode.AutoDetect));
Notice how this API very closely mirrors the XML configuration schema. Thus, you don't get any fluent API from the IObjectDefinitionRegistry interface, but at least there's an API which is decoupled from XML. Building a fluent API on top of this is at least theoretically possible.
You will find a fully working spring fluent API for spring.net on github:
https://github.com/thenapoleon/Fluent-API-for-Spring.Net
This API brings fluent configuration, and will soon support convention based configuration.
In answer to the first part of your question: the springsource team appears to be working on a code configuration project on github: https://github.com/SpringSource/spring-net-codeconfig. It was announced with (but not included in) the 1.3.1 (december 2010) release.
From the MovieFinder example:
[Configuration]
public class MovieFinderConfiguration
{
[Definition]
public virtual MovieLister MyMovieLister()
{
MovieLister movieLister = new MovieLister();
movieLister.MovieFinder = FileBasedMovieFinder();
return movieLister;
}
[Definition]
public virtual IMovieFinder FileBasedMovieFinder()
{
return new ColonDelimitedMovieFinder(new FileInfo("movies.txt"));
}
}
There is another option using the Spring.AutoRegistration. The same concept used with Unity AutoRegistration.
https://www.nuget.org/packages/Spring.AutoRegistration
http://autoregistration.codeplex.com/
var context = new GenericApplicationContext();
context.Configure()
.IncludeAssembly(x => x.FullName.StartsWith("Company.ApplicationXPTO"))
.Include(x => x.ImplementsITypeName(), Then.Register().UsingSingleton()
.InjectByProperty(If.DecoratedWith<InjectAttribute>))
.ApplyAutoRegistration();
It is also possible to use Spring.FluentContext project.
With it, the configuration of MovieFinder would look as follows:
// Configuration
private static IApplicationContext Configure()
{
var context = new FluentApplicationContext();
context.RegisterDefault<MovieLister>()
.BindProperty(l => l.MovieFinder).ToRegisteredDefaultOf<ColonDelimitedMovieFinder>();
context.RegisterDefault<ColonDelimitedMovieFinder>()
.UseConstructor((FileInfo fileInfo) => new ColonDelimitedMovieFinder(fileInfo))
.BindConstructorArg().ToValue(new FileInfo("movies.txt"));
return context;
}
// Usage
static void Main(string[] args)
{
IApplicationContext context = Configure();
var movieLister = context.GetObject<MovieLister>();
foreach (var movie in movieLister.MoviesDirectedBy("Roberto Benigni"))
Console.WriteLine(movie.Title);
Console.ReadLine();
}
It does not require any hardcoded literal ID for objects (but allows that), it is type safe and contains documentation with samples on GitHub wiki.
Using the Fluent-API-for-Spring.Net, the configuration could look something like:
private void ConfigureMovieFinder()
{
FluentApplicationContext.Clear();
FluentApplicationContext.Register<ColonDelimitedMovieFinder>("ColonDelimitedMovieFinder")
.BindConstructorArgument<FileInfo>().To(new FileInfo("movies.txt"));
// By default, fluent spring will create an identifier (Type.FullName) when using Register<T>()
FluentApplicationContext.Register<MovieLister>()
.Bind(x => x.MovieFinder).To<IMovieFinder>("ColonDelimitedMovieFinder");
}

Resources