Passing information between classes in a behaviour oriented design - vala

I decided to adapt my small text editor to the behaviour design pattern suggested in a previous question. It was soon clear how the behaviour design could help scale my little project by allowing adding key combinations to call the opening, saving actions and so on.
However, this design mainly uses classes and I am not sure how to make the classes communicate. A new class was added to handle saving the current file (SaveFile), but I am not being able to capture the URI of the current file (that was taken with the DocumentFileSelector class).
My suspicion is that the way to do that is through class properties, but I am not being able to actually make the document_selector variable inherit that property, so I could pass it to the SaveDocument class.
Here is the relevant part of the code:
uses
Gtk
init
Intl.setlocale()
Gtk.init (ref args)
var document = new Text( "Lorem Ipsum" )
var header = new Header ( "My text editor" )
var body = new DocumentView( document )
var editor = new EditorWindow (header,body )
var document_selector = new DocumentFileSelector( editor )
var load_new_content_command = new Load( document, document_selector )
var create_new = new CreateNew( document )
var save_file = new SaveFile( document )
header.add_item( new OpenButton( load_new_content_command ) )
header.add_item( new CreateNewButton ( create_new ) )
header.add_item( new SaveFileButton( save_file ))
editor.show_all ()
Gtk.main ()
class EditorWindow:Window
construct( header:Header, body:DocumentView )
this.window_position = WindowPosition.CENTER
this.set_default_size( 400, 400 )
this.destroy.connect( Gtk.main_quit)
this.set_titlebar(header)
var box = new Box (Gtk.Orientation.VERTICAL, 1)
box.pack_start(body, true, true, 0)
this.add(box)
class Header:HeaderBar
construct( title:string = "" )
this.show_close_button = true
this.set_title( title )
def add_item( item:Widget )
this.pack_start( item )
class SaveFileButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-save",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class OpenButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-open",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class CreateNewButton:ToolButton
construct( command:Command )
this.icon_widget = new Image.from_icon_name(
"document-new",
IconSize.SMALL_TOOLBAR
)
this.clicked.connect( command.execute )
class DocumentView:ScrolledWindow
construct( document:TextBuffer )
var view = new TextView.with_buffer( document )
view.set_wrap_mode( Gtk.WrapMode.WORD )
this.add( view )
interface Command:Object
def abstract execute()
interface DocumentSelector:Object
def abstract select():bool
def abstract get_document():string
class Text:TextBuffer
construct ( initial:string = "" )
this.text = initial
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_filename, _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)
class Load:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector )
_receiver = receiver
_document_selector = document_selector
def execute()
if _document_selector.select()
_receiver.text = _document_selector.get_document()
class CreateNew:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
var should_I_save=new MessageDialog (null, Gtk.DialogFlags.MODAL,
Gtk.MessageType.INFO, Gtk.ButtonsType.YES_NO, "Hello world!")
should_I_save.format_secondary_text (
"This will delete the contets. Are you sure?")
case should_I_save.run()
when ResponseType.YES
_receiver.set_text("")
should_I_save.destroy ()
when ResponseType.NO
should_I_save.destroy ()
Question
How to pass the URI information from the last file opened to the SaveDocument class?
As an extra question, the first line after the construct of each class is doing what? The lines that read like:
construct( parent:Window )
_parent = parent
Edit
Still couldn't solve the problem, something I recently tried was to create another method inside DocumentFileSelector class called whichFile(). This method would only return the uri. I am getting the error at execution: FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false)).
And here are the modifications to the code:
class SaveFile:Object implements Command
_receiver:TextBuffer
construct( receiver:TextBuffer )
_receiver = receiver
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents ( DocumentFileSelector.whichFile(), _receiver.get_text(start, end,false))
except ex : FileError
print "%s\n", ex.message
class DocumentFileSelector:Object implements DocumentSelector
_parent:Window
_uri:string = ""
construct( parent:Window )
_parent = parent
def select():bool
var dialog = new FileChooserDialog( "Open file",
_parent,
FileChooserAction.OPEN,
dgettext( "gtk30", "_OK"),
ResponseType.ACCEPT,
dgettext( "gtk30", "_Cancel" ),
ResponseType.CANCEL
)
selected:bool = false
var response = dialog.run()
case response
when ResponseType.ACCEPT
_uri = dialog.get_uri()
selected = true
dialog.destroy()
return selected
def whichFile():string
return _uri
def get_document():string
return "Reading the text from a URI is not implemented\n%s".printf(_uri)

You're almost there ...
Just add a reference to the DocumentSelector to your SaveFile command as you did for the LoadFile command:
class SaveFile:Object implements Command
_receiver:TextBuffer
_document_selector:DocumentSelector
construct( receiver:TextBuffer, document_selector:DocumentSelector)
_receiver = receiver
_document_selector = document_selector
You can then invoke your new whichFile() method on the saved DocumentSelector:
def execute()
start, end : Gtk.TextIter
_receiver.get_start_iter(out start)
_receiver.get_end_iter(out end)
try
FileUtils.set_contents (_document_selector.whichFile(), _receiver.get_text(start, end,
false))
except ex : FileError
print "%s\n", ex.message

Related

HOW to MERGE in neo4j using JAVA

Hi I am trying to insert two properties of a node....I am trying like below..
I am trying to add two properties to CUSTOMER NODE
1.name and 2.TOTAL_CALL_DURATION
How can I add two properties
try ( Transaction tx = graphDb.beginTx() )
{
String queryString = "MERGE (n:CUSTOMER {name:{name},TOTAL_CALL_DURATION:{TOTAL_CALL_DURATION}}) RETURN n";
Map<String, Object> callerProperties = new HashMap<>();
callerProperties.put( "name", callerName );
callerProperties.put("TOTAL_CALL_DURATION", 120);
resultIterator_caller = execEngine.execute( queryString, callerProperties ).columnAs( "n" );
tx.success();
}
The error I am getting like below:
Exception in thread "main" org.neo4j.cypher.ParameterNotFoundException: Expected a parameter named TOTAL_CALL_DURATION
at org.neo4j.cypher.internal.compiler.v2_1.pipes.QueryState$$anonfun$getParam$1.apply(QueryState.scala:45)
at org.neo4j.cypher.internal.compiler.v2_1.pipes.QueryState$$anonfun$getParam$1.apply(QueryState.scala:45)
at scala.collection.MapLike$class.getOrElse(MapLike.scala:128)
at scala.collection.AbstractMap.getOrElse(Map.scala:58)
at org.neo4j.cypher.internal.compiler.v2_1.pipes.QueryState.getParam(QueryState.scala:45)
at org.neo4j.cypher.internal.compiler.v2_1.commands.expressions.ParameterExpression.apply(ParameterExpression.scala:27)
at org.neo4j.cypher.internal.compiler.v2_1.helpers.PropertySupport$$anonfun$firstNullPropertyIfAny$1.isDefinedAt(PropertySupport.scala:29)
at org.neo4j.cypher.internal.compiler.v2_1.helpers.PropertySupport$$anonfun$firstNullPropertyIfAny$1.isDefinedAt(PropertySupport.scala:28)
at scala.collection.TraversableOnce$$anonfun$collectFirst$1.apply(TraversableOnce.scala:132)
at scala.collection.TraversableOnce$$anonfun$collectFirst$1.apply(TraversableOnce.scala:131)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at scala.collection.AbstractIterator.foreach(Iterator.scala:1157)
at scala.collection.TraversableOnce$class.collectFirst(TraversableOnce.scala:131)
at scala.collection.AbstractTraversable.collectFirst(Traversable.scala:105)
at org.neo4j.cypher.internal.compiler.v2_1.helpers.PropertySupport$.firstNullPropertyIfAny(PropertySupport.scala:28)
at org.neo4j.cypher.internal.compiler.v2_1.mutation.MergeNodeAction.ensureNoNullNodeProperties(MergeNodeAction.scala:95)
at org.neo4j.cypher.internal.compiler.v2_1.mutation.MergeNodeAction.exec(MergeNodeAction.scala:73)
at org.neo4j.cypher.internal.compiler.v2_1.pipes.ExecuteUpdateCommandsPipe.org$neo4j$cypher$internal$compiler$v2_1$pipes$ExecuteUpdateCommandsPipe$$exec(ExecuteUpdateCommandsPipe.scala:57)
at org.neo4j.cypher.internal.compiler.v2_1.pipes.ExecuteUpdateCommandsPi$$$$1019fdff8b266d7d9d5647386930b3d8$$$$ands$1$$anonfun$apply$2.apply(ExecuteUpdateCommandsPipe.scala:46)
at org.neo4j.cypher.internal.compiler.v2_1.pipes.ExecuteUpdateCommandsPi$$$$1019fdff8b266d7d9d5647386930b3d8$$$$ands$1$$anonfun$apply$2.apply(ExecuteUpdateCommandsPipe.scala:46)
at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
at scala.collection.Iterator$$anon$13.hasNext(Iterator.scala:371)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator$$anonfun$hasNext$1.apply$mcZ$sp(ClosingIterator.scala:37)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:34)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator$$anonfun$hasNext$1.apply(ClosingIterator.scala:34)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator$$anonfun$failIfThrows$1.apply(ClosingIterator.scala:93)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.decoratedCypherException(ClosingIterator.scala:102)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.failIfThrows(ClosingIterator.scala:91)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.hasNext(ClosingIterator.scala:34)
at scala.collection.Iterator$class.foreach(Iterator.scala:727)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.foreach(ClosingIterator.scala:28)
at scala.collection.generic.Growable$class.$plus$plus$eq(Growable.scala:48)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:176)
at scala.collection.mutable.ListBuffer.$plus$plus$eq(ListBuffer.scala:45)
at scala.collection.TraversableOnce$class.to(TraversableOnce.scala:273)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.to(ClosingIterator.scala:28)
at scala.collection.TraversableOnce$class.toList(TraversableOnce.scala:257)
at org.neo4j.cypher.internal.compiler.v2_1.ClosingIterator.toList(ClosingIterator.scala:28)
at org.neo4j.cypher.internal.compiler.v2_1.EagerPipeExecutionResult.<init>(EagerPipeExecutionResult.scala:32)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:125)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1$$anonfun$apply$2.apply(ExecutionPlanBuilder.scala:119)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionWorkflowBuilder.runWithQueryState(ExecutionPlanBuilder.scala:168)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:118)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anonfun$getExecutionPlanFunction$1.apply(ExecutionPlanBuilder.scala:103)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:68)
at org.neo4j.cypher.internal.compiler.v2_1.executionplan.ExecutionPlanBuilder$$anon$1.execute(ExecutionPlanBuilder.scala:67)
at org.neo4j.cypher.internal.ExecutionPlanWrapperForV2_1.execute(CypherCompiler.scala:159)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:76)
at org.neo4j.cypher.ExecutionEngine.execute(ExecutionEngine.scala:71)
at org.neo4j.cypher.javacompat.ExecutionEngine.execute(ExecutionEngine.java:84)
at com.emc.neo4jConnectivity.NodeCreation.createNodes(NodeCreation.java:84)
at com.emc.neo4jConnectivity.NodeCreation.main(NodeCreation.java:136)
There's nothing wrong with your code, I've converted it into a self-contained groovy script running fine without any errors.
Try to provide a minimal viable testcase showing the error you're observing
For reference, here's the script:
#Grapes([
#Grab(group="org.neo4j", module="neo4j-kernel", version="2.1.8", classifier="tests"),
#Grab(group="org.neo4j", module="neo4j-kernel", version="2.1.8"),
#Grab(group="org.neo4j", module="neo4j-cypher", version="2.1.8")
])
import org.neo4j.test.TestGraphDatabaseFactory
import org.neo4j.cypher.javacompat.ExecutionEngine
import org.neo4j.helpers.collection.IteratorUtil
def graphDb = new TestGraphDatabaseFactory().newImpermanentDatabaseBuilder().newGraphDatabase()
def executionEngine = new ExecutionEngine(graphDb)
def resultIterator_caller
def tx = graphDb.beginTx()
try {
String queryString = "MERGE (n:CUSTOMER {name:{name},TOTAL_CALL_DURATION:{TOTAL_CALL_DURATION}}) RETURN n";
Map<String, Object> callerProperties = new HashMap<>();
callerProperties.put( "name", "abc" );
callerProperties.put("TOTAL_CALL_DURATION", 120);
resultIterator_caller = executionEngine.execute( queryString, callerProperties ).columnAs( "n" );
tx.success()
} finally {
tx.close()
}
// we need another tx to consume the result (since we're returning node instances)
transaction = graphDb.beginTx()
try {
assert resultIterator_caller.hasNext()
def nextNode = resultIterator_caller.next()
assert nextNode.getProperty("name",null) == "abc"
assert nextNode.getProperty("TOTAL_CALL_DURATION",null) == 120
assert !resultIterator_caller.hasNext()
tx.success()
} finally {
tx.close()
}

Drools mode stream and containers

HI this is my code.
public static KieContainer createKieContainerForProject() {
KieServices ks = KieServices.Factory.get();
// Create a module model
KieModuleModel kieModuleModel = ks.newKieModuleModel();
// Base Model from the module model
KieBaseModel kieBaseModel = kieModuleModel.newKieBaseModel( "KBase" )
.setDefault( true )
.setEqualsBehavior( EqualityBehaviorOption.EQUALITY)
.setEventProcessingMode( EventProcessingOption.STREAM );
// Create session model for the Base Model
KieSessionModel ksessionModel = kieBaseModel.newKieSessionModel( "KSession" )
.setDefault( true )
.setType( KieSessionModel.KieSessionType.STATEFUL )
.setClockType( ClockTypeOption.get("realtime") );
// Create File System services
KieFileSystem kFileSystem = ks.newKieFileSystem();
File file = new File("src/main/resources/rules/Sample.drl");
Resource resource = ks.getResources().newFileSystemResource(file).setResourceType(ResourceType.DRL);
kFileSystem.write( resource );
KieBuilder kbuilder = ks.newKieBuilder( kFileSystem );
// kieModule is automatically deployed to KieRepository if successfully built.
kbuilder.buildAll();
if (kbuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
throw new RuntimeException("Build time Errors: " + kbuilder.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(ks.getRepository().getDefaultReleaseId());
return kContainer;
}
}
it's dont work when I call the fucntion, and my rules no work too.
my rule is
rule "Sound the alarm in case temperature rises above threshold"
when
TemperatureThreshold( $max : max )
Number( doubleValue > $max ) from accumulate(
SensorReading( $temp : temperature ) over window:time( 10m ),
average( $temp ) )
then
// sound the alarm
end
when I run the program, He says it has error, mode not stream and the code dont work.
how do I put a program in stream mode?
REduce your code, and add -KieBase and KieSession creation:
KieServices ks = KieServices.Factory.get();
KieFileSystem kFileSystem = ks.newKieFileSystem();
FileInputStream fis = new FileInputStream( "...drl" );
kFileSystem.write("src/main/resources/somename.drl",
ks.getResources().newInputStreamResource( fis ) ); //XXX
KieBuilder kbuilder = ks.newKieBuilder( kFileSystem );
kbuilder.buildAll();
if (kbuilder.getResults().hasMessages(org.kie.api.builder.Message.Level.ERROR)) {
throw new RuntimeException("Build time Errors: " + kbuilder.getResults().toString());
}
KieContainer kContainer = ks.newKieContainer(ks.getRepository().getDefaultReleaseId());
KieBaseConfiguration config = ks.newKieBaseConfiguration();
config.setOption(EventProcessingOption.STREAM);
KieBase kieBase = kContainer.newKieBase( config );
KieSession kieSession = kieBase.newKieSession();
This should give you a session that's capable of running your rule. (
According to the docs, it's as follows:
KieBaseConfiguration config = KieServices.Factory.get().newKieBaseConfiguration();
config.setOption( EventProcessingOption.STREAM );
But it's probably worth taking a look at this Drools test for a working example.

Reading JSON object from txt file in Groovy

I am trying to collect a JSON from a txt file. But my below code seems to keep giving me "nullPointerException".
File f = new File(tempDir+File.separator+'jsonObject.txt')
if (f){
log.error " file exists $f"
FileReader f2 = new FileReader(f);
log.error " file data- $f2"
if (f2 == null) {
//do something
} else {
JsonSlurper jsonParser = new JsonSlurper();
game = jsonParser.parse(new FileReader(f));
}
}
SOLUTION FOUND
Reading a json txt file:
File f = new File(tempDir+File.separator+'jsonObject.txt')
def slurper = new JsonSlurper()
def jsonText = f.getText()
json = slurper.parseText( jsonText )
Writing json to a file:
File g = new File(tempDir+File.separator+'jsonObject.txt')
g.createNewFile()
def json = new JsonBuilder()
json {
"result" result
}
g.setText(json.toString())
Please, try this:
import groovy.json.JsonSlurper
def inputFile = new File("D:\\yourPath\\json.txt")
def InputJSON = new JsonSlurper().parseText(inputFile.text)
InputJSON.each{ println it }
try:
File f = new File( tempDir, 'jsonObject.txt' )
if( f.exists() ) {
def game = f.withReader { r ->
new JsonSlurper().parse( r )
}
println game
}
Try simple and optimized solution:
import groovy.json.JsonSlurper
try {
File inputFile = new File("your_file_path")
def slurper = new JsonSlurper()
def data = slurper.parse(inputFile)
} catch (Exception e) {
e.printStackTrace()
}
parseFile can take a file as an input:
import groovy.json.JsonSlurper
def inputFile = new File("/your/path/my.json")
def InputJSON = new JsonSlurper().parseFile(inputFile, 'UTF-8')
InputJSON.each{ println it }

delete an existing file in grails

I am saving image files in my web folder. But at the time of saving or suppose a user want to change his picture than i want to delete the old picture and save the new one with the same file name. But I am failing after trying. Can anyone please help me on this please? Here is all my action below :
my save action >>>
def savePicture = {
String message = ""
def user = User.findById(1)
def userId = user.id
MultipartHttpServletRequest mpr = (MultipartHttpServletRequest)request;
CommonsMultipartFile f = (CommonsMultipartFile) mpr.getFile("productPic");
def okcontents = ['image/png', 'image/jpeg', 'image/gif']
if (! okcontents.contains(f.getContentType())) {
message = "Avatar must be one of: ${okcontents}"
render(view:'uploadForm', model:[message: message])
return;
}
String type = f.getContentType().substring(6)
String baseImageName = java.util.UUID.randomUUID().toString();
baseImageName = "user${user.id}"
// Saving image in a folder assets/channelImage/, in the web-app, with the name: baseImageName
def downloadedFile = f //.getFile( "product.baseImage" )
String fileUploaded = fileUploadService.uploadFile( downloadedFile, "${baseImageName}.${type}", "assets/channelImage/" )
if( fileUploaded ){
user.avatarType = type
user.save()
message = "File Saved Successfully."
redirect(action: 'show', params: [userId: userId])
}
}
my service action where I am trying to delete before save >>>
def String uploadFile( MultipartFile file, String name, String destinationDirectory ) {
def serveletContext = ServletContextHolder.servletContext
def storagePath = serveletContext.getRealPath( destinationDirectory )
def storagePathDirectory = new File("${storagePath}/${name}").delete()
// Store file
if(!file.isEmpty()){
file.transferTo( new File("${storagePath}/${name}") )
println("Saved File: ${storagePath}/${name}")
return "${storagePath}/${name}"
}else{
println "File: ${file.inspect()} was empty"
return null
}
}
my show method in controller >>>
def show = {
Long uid = Long.parseLong(params.userId)
def avatarUser = User.get(uid)
String link = "user${avatarUser.id}.${avatarUser.avatarType}"
[link:link]
}
my view page >>>
<g:if test="${link}">
<img src="${resource(dir: 'assets/channelImage', file: "${link}")}" />
</g:if>

How do you return values from javascript functions

I'm using the js library in Dart to access OpenLayers. Pertinent code looks like:
js.scoped(() {
ol = js.retain(js.context.OpenLayers);
var max_extent = new js.Proxy(ol.Bounds, -13652354.432172, 6026153.418145, -13574082.915218, 6065289.1766216);
var restricted_extent = max_extent;
if (controls == null){
var options = js.map ({
'maxExtent': max_extent,
'restrictedExtent' : restricted_extent,
'units' : 'm',
'projection': new js.Proxy(ol.Projection, 'EPSG:900913'),
'displayProjection' : new js.Proxy(ol.Projection, 'EPSG:4326'),
'controls' : js.array([ new js.Proxy(ol.Control.Attribution),
new js.Proxy(ol.Control.Navigation),
new js.Proxy(ol.Control.ArgParser),
new js.Proxy(ol.Control.PanPanel),
new js.Proxy(ol.Control.ZoomPanel)
])
});
_treemap = js.retain( new js.Proxy( ol.Map, map_div_id, options ) );
}
var roads = new MapLayer(ol, layer_type:'road').layer;
var aerial = new MapLayer(ol, layer_type:'hybrid').layer;
_treemap.addLayers(js.array([roads, aerial]));
_treemap.setBaseLayer(roads);
_treemap.zoomToMaxExtent();
var result = _treemap.layers();
});
All works as expected except for the last line. _treemap.layers() is supposed to return an array of OpenLayer.Layer. When that line executes I get an error:
Exception: TypeError: Object [object Array] has no method 'apply'
So, what is the correct way to get/handle return values from javascript functions in my Dart code?
layers is an array (see OpenLayers.Map.layers). So you should use :
var result = _treemap.layers;
With _treemap.layers() you was trying to call layers as it was a function.
One side note on your code : when you use js.map({}) you don't need to use js.array or js.map in the object tree. You can simply give a JSON-like structure.
var options = js.map ({
'maxExtent': max_extent,
'restrictedExtent' : restricted_extent,
'units' : 'm',
'projection': new js.Proxy(ol.Projection, 'EPSG:900913'),
'displayProjection' : new js.Proxy(ol.Projection, 'EPSG:4326'),
'controls' : [ new js.Proxy(ol.Control.Attribution),
new js.Proxy(ol.Control.Navigation),
new js.Proxy(ol.Control.ArgParser),
new js.Proxy(ol.Control.PanPanel),
new js.Proxy(ol.Control.ZoomPanel)
])
});

Resources