# Using JS file across UX files

**URL:** <https://forums.fusetools.com/t/using-js-file-across-ux-files/6869>\
**Category:** How-to Discussions\
**Created:** [September 4, 2016, 7:47pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869 "2016-09-04T19:47:36Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Fotis](https://avatars.discourse-cdn.com/v4/letter/f/4af34b/32.png) [@Fotis](https://forums.fusetools.com/u/Fotis)\
**Post date:** [September 4, 2016, 7:47pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/1 "2016-09-04T19:47:36Z")

</div>

Hello,

In our app we have a `navigator` with two templates (`MainPage and SideBar`). In `Sidebar` we use `PageControl` in order to achieve a tabbed layout menu as in cattr example.

```auto
<App>
	<Router ux:Name="router" />
	<Navigator DefaultTemplate="MainPage">
		<MainPage ux:Template="MainPage" router="router" />
		<SideBar ux:Template="SideBar" router="router" />
	</Navigator>
</App>

```

This is the `Sidebar.ux` file

```auto
<Router ux:Dependency="router"/>
<DockPanel Background="#212831">
	<DockPanel>
		<Panel Dock="Top" Height="5%" Margin="0,10,0,0">
			<Grid ColumnCount="4" Columns="3*,3*,3*,1*" Background="#212831">
				<HomePageTab Label="Movies" pageControl="pageControl" page="movies" />
				<HomePageTab Label="Genres" pageControl="pageControl" page="genres" />
				<HomePageTab Label="Year" pageControl="pageControl" page="year" />
			</Grid>
		</Panel>
		<PageControl ux:Name="pageControl" Height="95%">
			<MoviePage ux:Name="movies" />
			<Genres ux:Name="genres" />
			<Year ux:Name="year" />
		</PageControl>
	</DockPanel>
	<StatusBarBackground Dock="Top" Background="#212831" />
</DockPanel>

```

For each object in `PageControl` we have a .ux and .js file.  
When an element from Movie.ux is clicked, a JS function that fetches the movies is called. The Movies are stored in an Observable.  
We want to use the Observable values to the MainPage but it seems to be empty. Is there a way to achieve this ? We tried using JS modules following the YouTube example but it’s still empty.

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [September 4, 2016, 9:28pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/2 "2016-09-04T21:28:43Z")

</div>

Hi!

It is really hard to answer your question without seeing the JS code in question. Can you please upload a full project? Or at least show all relevant code? Thanks.

---

<div class="post-metadata">

**Author:** ![Fotis](https://avatars.discourse-cdn.com/v4/letter/f/4af34b/32.png) [@Fotis](https://forums.fusetools.com/u/Fotis)\
**Post date:** [September 4, 2016, 9:52pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/3 "2016-09-04T21:52:46Z")

</div>

Hello, and thanks for the reply !!

Here is the main JS code that i have

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

var genre = Observable();
var movies = Observable();
var test = Observable();
var moreInfo = Observable();
var genreID = [];
var changed = 0;
var open = 0;
var yearFilter = 0;
var categorieSearch = 0;
var moviesObs = Observable();
var searchText = Observable();
var activePage = Observable("");
var experience = Observable(1900);
var yearText = Observable(function() { return "Year " + parseInt(experience.value); });
var canSwipe = Observable(true);1
var infoAnimation = Observable(false);
var _progress = Observable(false);
var movieExists = Observable(true);

var movie_url = 'https://api.themoviedb.org/3/discover/movie'+apiKey;
var fetch_more_url = "http://api.themoviedb.org/3/movie/";

var ids = {Adventure:"12", Action:"28", Animation:"16" , Comedy:"35" , Crime:"80" , Documentary:"99" , Drama:"18" , Family:"10751" , Foreign:"10769" , Fantasy:"14" ,History:"36" , Horror:"27" , Music:"10402" , Mystery:"9648" , Romance:"10749" , "Science Fiction":"878" , "TV Movie":"10770" , Thriller:"53" ,War:"10752" , Western:"37"};
var titleInput = Observable("");

function addHandler(args)
{
    var value = args.data.item.name;
    if(!genre.contains(value))
    {
        genre.add(value);
    }
    else{
        genre.remove(value);
        genreID.splice(genreID.indexOf(ids[value]),1);
    }
    changed = 1;
    gerneToID();
}

function gerneToID(args)
{
    for(i=0;i<genre.length;i++)
    {
        if(genreID.indexOf(ids[genre.getAt(i)]) == -1)
        {
            genreID.push(ids[genre.getAt(i)]);
        }
    }
}

function clickAction(args)
{
	movie_url = 'https://api.themoviedb.org/3/movie';
	var value = args.data.item;
	value = value.toLowerCase();
	value = value.replace(" ","_");
	movie_url += '/'+value+apiKey;
    changed = 1;
    categorieSearch = 1;
	getGenre();
}

function getGenre()
{
    var posterBase = "https://image.tmdb.org/t/p";
    var posterSize = "/w500";
    var poster = posterBase+posterSize;

    if(yearFilter === 1)
    {
        movie_url = 'https://api.themoviedb.org/3/discover/movie'+apiKey+'&with_genres='+genreID+"&release_date.gte="+parseInt(experience.value)+"-01-01";
    }
    else if(genreID.length != 0 && categorieSearch === 0) {
        movie_url = 'https://api.themoviedb.org/3/discover/movie'+apiKey+'&with_genres='+genreID;
    }

	if(changed)
	{
		_progress.value = true;
		if(canSwipe.value == false)
		{
			canSwipe.value = true;
			infoAnimation.value = false;
		}

        console.log("Movie : "+movie_url); // TODO delete later
		moviesObs.clear();
	    var fetchJson = function(url) {
	        return fetch(url).then(function(response) { return response.json(); });
	    };

	    var createMovieAsync = function(jsonMovie, index) {
	        var genres = [];
	        var moreinfoUrl = fetch_more_url + jsonMovie.id+apiKey+"&append_to_response=credits";

			if(index < 10)
			{
		        return fetchJson(moreinfoUrl).then(function(moreinfo) {
		            moreinfo.genres.forEach(function(genreName){
		                genres.push(genreName.name);
		            });

					var backPath = jsonMovie.backdrop_path;
					if(backPath == null)
					{
						backPath = jsonMovie.poster_path;
					}

					var releaseDate = jsonMovie.release_date.split("-");
					var year = releaseDate[0];

					var duration = moreinfo.runtime;
					var runtime = moreinfo.runtime;
					if(duration == 0)
					{
						duration = "--";
						runtime = "--";
					} else {
						var h = Math.floor(duration / 60);
						var m = duration % 60;
						duration = h + "h " + m + "m";
					}

                    fetchJson(trailerUrl)
                        .then(function(responseObject){
							responseObject.results.forEach(function(trailer){
							});
                        });

		            return {
		                poster_path: poster + jsonMovie.poster_path,
						backdrop_path : poster + backPath,
		                runtime : runtime,
						duration : duration,
		                title: jsonMovie.title,
		                genre: genres.join(", "),
						year : year,
						rating : jsonMovie.vote_average,
						plot : jsonMovie.overview
		            };
		        });
			}
	    };

		fetchJson(movie_url)
			.then(function(responseObject){
				numOfPages = responseObject.total_pages;
				numOfResults = responseObject.total_results;
                if(!categorieSearch)
                {
    				if(numOfPages < 1000) // API cannot return results for pages over 1000
    	    	    {
    	    	        page = Math.floor((Math.random() * numOfPages) + 1);
    	    	    }
    	    	    else {
    	    	        page = Math.floor((Math.random() * 1000) + 1);
    	    	    }
    	    	    movie_url+="&page="+page; // TODO delete later , 283 page have movie with long title
					console.log(movie_url);
                }
				categorieSearch=0;
			})
			.then(function(){
				if(numOfResults > 0)
				{
					movieExists.value = true;
					fetchJson(movie_url)
			        .then(function(responseObject) {
						return responseObject.results.map(createMovieAsync)
					})
			        .then(function(promises) { return Promise.all(promises); }) // Wait for all movies to fetch more info
			        .then(function(movies) {
			            movies.map(function(m, index) {
							if(index < 10)
			                	moviesObs.add(m) // Add to observable
			            });
						_progress.value = false;
			        })
			        .catch(function(e) { console.log("error :("); }); // TODO later we dont need to have this error message
				}
				else {
					_progress.value = false;
					movieExists.value = false;
				}
			});
	}
	changed=0;
}

function navigatorAction()
{
	router.goto("SideBar");
}

function yearChange()
{
    yearFilter = 1;
    changed = 1;
	yearText.value = "Year: " + parseInt(experience.value);
}

function click()
{
	if(canSwipe.value == false)
	{
		canSwipe.value = true;
		infoAnimation.value = false;
	} else {
		canSwipe.value = false;
		infoAnimation.value = true;
	}
}

module.exports = {
    addHandler: addHandler,
    gerneToID: gerneToID,
    getGenre: getGenre,
    movieList: moviesObs,
    navigatorAction: navigatorAction,
    clickAction: clickAction,
    yearText: yearText,
 	experience : experience,
 	yearChange : yearChange,
	click : click,
	canSwipe : canSwipe,
	infoAnimation : infoAnimation,
	_progress : _progress,
	movieExists : movieExists
};

```

what i am trying to do is have this code as “global”. What i mean is that i want to fetch the info about the movies inside `MoviePage` etc and to be able to preview the results on `MainPage`.

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [September 4, 2016, 9:54pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/4 "2016-09-04T21:54:49Z")

</div>

To create a global module, simply create a plain JS file somewhere, say `Foo.js`, and `require("Foo")` wherever you need it.

Make sure `Foo.js` is in the `:Bundle`, e.g.

```
"*.js:Bundle"

```

in your `.unoproj`

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [September 4, 2016, 9:56pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/5 "2016-09-04T21:56:16Z")

</div>

Note that the module will _not_ be global if you point to it with `JavaScript File="`. That creates a view local copy of the module for each instance of the containing view.

---

<div class="post-metadata">

**Author:** ![Fotis](https://avatars.discourse-cdn.com/v4/letter/f/4af34b/32.png) [@Fotis](https://forums.fusetools.com/u/Fotis)\
**Post date:** [September 4, 2016, 9:56pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/6 "2016-09-04T21:56:21Z")

</div>

And using this will have the same “data” ( from the JS ) across all the UX files ?

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [September 4, 2016, 9:58pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/7 "2016-09-04T21:58:46Z")

</div>

Yes. `require()` always returns exactly the same object every time for the same module name.

---

<div class="post-metadata">

**Author:** ![Fotis](https://avatars.discourse-cdn.com/v4/letter/f/4af34b/32.png) [@Fotis](https://forums.fusetools.com/u/Fotis)\
**Post date:** [September 4, 2016, 10:00pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/8 "2016-09-04T22:00:29Z")

</div>

Okay i see… but as i saw in the tutorial video about modules… it said that `require()` is executed immediately but that isn’t what i need. I want to execute it on demand… can i do this somehow ?

---

<div class="post-metadata">

**Author:** ![Anders\_Lassen](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/anders_lassen/32/522_2.png) [@Anders\_Lassen](https://forums.fusetools.com/u/Anders_Lassen)\
**Post date:** [September 4, 2016, 10:55pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/9 "2016-09-04T22:55:48Z")

</div>

Make a function inside your module, export that function, call it on demand.

---

<div class="post-metadata">

**Author:** ![Fotis](https://avatars.discourse-cdn.com/v4/letter/f/4af34b/32.png) [@Fotis](https://forums.fusetools.com/u/Fotis)\
**Post date:** [September 6, 2016, 3:57pm UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/10 "2016-09-06T15:57:06Z")

</div>

Thank you very much !! It worked as you said ( once i remembered that i have to export the function in order to work 😃 ) Very nice and smart way using the modules. It just makes it a whole lot easier 😃

---

<div class="post-metadata">

**Author:** ![sed](https://yyz1.discourse-cdn.com/flex035/user_avatar/forums.fusetools.com/sed/32/814_2.png) [@sed](https://forums.fusetools.com/u/sed)\
**Post date:** [January 11, 2019, 8:01am UTC](https://forums.fusetools.com/t/using-js-file-across-ux-files/6869/11 "2019-01-11T08:01:04Z")

</div>

Thank you 😘😘 that was helpfull.
