function re-call from js

Hi,

I have a problem, when calling a function from a.js in b.js that then calls a function in a.js. Heres the example:

testapp2.unoproj

{
  "RootNamespace":"",
  "Packages": [
    "Fuse",
    "FuseJS"
  ],
  "Includes": [
    "*",
    "*.js:Bundle"
  ]
}

Mainview.ux:

<App>
	<JavaScript File="b.js" />
	<JavaScript File="a.js" />

	<Button Text="fooa" Clicked="{fooa}" />
</App>

a.js:

b = require('b');

function fooa(){
	b.foob(); // calling the function from ux works without error
}

function bara(){
	console.log("bar a")
}

b.foob(); // this is what causes the error

module.exports = {
	fooa: fooa,
	bara: bara
}

b.js:

a = require('a');

function foob(){
	a.bara(a);
}

module.exports = {
	foob: foob
}

If I comment out the b.barb() in a.js, I can press the ux button and everything works fine, but if call the function directly from a.js, then I get this error:

Error: TypeError: a.bara is not a function: Name: TypeError: a.bara is not a function
Error message: Uncaught TypeError: a.bara is not a function
File name: b.js
Line number: 4
Source line: 	a.bara(a);
JS stack trace: TypeError: a.bara is not a function
    at Object.foob (b.js:4:4)
    at a.js:11:3
    at Object._tempMethod (b.js:1:53)
 in Fuse.Reactive.DiagnosticSubject<b.js:4>
Error: TypeError: a.bara is not a function: Name: TypeError: a.bara is not a function
Error message: Uncaught TypeError: a.bara is not a function
File name: b.js
Line number: 4
Source line: 	a.bara(a);
JS stack trace: TypeError: a.bara is not a function
    at Object.foob (b.js:4:4)
    at Object._tempMethod (a.js:11:3)
 in Fuse.Reactive.DiagnosticSubject<b.js:4>

So why can I call it through ux, but not from js and how can I get it working from js?

I found a workaround, but its not really satisfying:

I use a switch to trigger a callback in the ux from js:

a.js:

var Observable = require('FuseJS/Observable');

b = require('b');

var callfromui = Observable(false);

function fooa(){
	b.foob();
	callfromui.value = false;
}

function bara(){
	console.log("bar a")
}

callfromui.value = true;

module.exports = {
	fooa: fooa,
	bara: bara,
	callfromui: callfromui
}

Mainview.ux:

<App>
	<JavaScript File="b.js" />
	<JavaScript File="a.js" />

	<WhileTrue Value="{callfromui}">
    	   <Callback Handler="{fooa}" />
	</WhileTrue>

	<Button Text="fooa" Clicked="{fooa}" />
</App>

It works, but I hope there is a better more comfortable way to do it.

Hi,

the root cause of the problem you’re facing is right there:

<App>
    <JavaScript File="b.js" />
    <JavaScript File="a.js" />

A single UX component can only have a single viewmodel (the JS data context). Here, you have two. That won’t work.

Please start reading here and follow the links to understand the concept and we can take it from there. You’ll find some more tips if you search the forum for MVVM.

Hope this helps!

Hi Uldis,

thanks for the reply. These links helped and I splitted things up in a proper viewmodel and model structure. But the problem still exists, that I cannot re-call the functions between 2 models (non-viewmodel). In this example a.js and b.js would be models and there would actually be no viewmodel necessary for this example. But I will re-read and try to find out what I am missing. For now I solved it by outsourcing the bara function into a third model, so no model is calling itself through another model.

Hendrik wrote:
[…] no model is calling itself through another model.

That’s the part I did not want to start explaining before you got the MVVM basics down :slight_smile:

A given model “A” should never require() another model “B” that require()s the model “A”. The relationship between models is meant to be exclusive.