Using JS file across UX files

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.

<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

<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.

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.

Hello, and thanks for the reply !!

Here is the main JS code that i have

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.

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

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.

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

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

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 ?

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

1 Like

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

Thank you :kissing_heart::kissing_heart: that was helpfull.