Meteor: Importing a JS file isn't working - meteor

I have created a JS file inside the lib folder which has a JSON Object assigned to a variable and i am trying to use that variable in the Client folder, in of the template helper function but i get error while running saying the variable isn't defined.
How to solve this ? How to use this variable in both Client and Server ?
deviceMap.js -> inside lib folder
var deviceMap = {
"123456": {
"name": "ABC",
"department": "dept1"
}
}
Template.tmp1.helpers({
console.log(deviceMap);
});
Thank you

Prior to meteor 1.3, the only way to share variables between files is through the global namespace.
Replace:
var deviceMap =
with:
deviceMap =
and your variable will be global instead of file scoped. You may also want to consider namespacing your variable like: DeviceMaps.departments or something.

Related

How to pass a parameter from the Jupyter backend to a frontend extension

I currently have a value that is stored as an environment variable the environment where a jupyter server is running. I would like to somehow pass that value to a frontend extension. It does not have to read the environment variable in real time, I am fine with just using the value of the variable at startup. Is there a canonical way to pass parameters a frontend extension on startup? Would appreciate an examples of both setting the parameter from the backend and accessing it from the frontend.
[update]
I have posted a solution that works for nbextentions, but I can't seem to find the equivalent pattern for labextensions (typescript), any help there would be much appreciated.
I was able to do this by adding the following code to my jupter_notebook_config.py
from notebook.services.config import ConfigManager
cm = ConfigManager()
cm.update('notebook', {'variable_being_set': value})
Then I had the parameters defined in my extension in my main.js
// define default values for config parameters
var params = {
variable_being_set : 'default'
};
// to be called once config is loaded, this updates default config vals
// with the ones specified by the server's config file
var update_params = function() {
var config = Jupyter.notebook.config;
for (var key in params) {
if (config.data.hasOwnProperty(key) ){
params[key] = config.data[key];
}
}
};
I also have the parameters declared in my main.yaml
Parameters:
- name: variable_being_set
description: ...
input_type: text
default: `default_value`
This took some trial and error to find out because there is very little documentation on the ConfigManager class and none of it has an end-to-end example.

QT Installer Controller Script crash while "addWizardPage"

I got some problems with the QT Installer - already done all tutorials (especially http://doc.qt.io/qtinstallerframework/noninteractive.html) but i am still a real newbie
What i need:
an installer with a language Selection as first page
adding a second (save) path in TargetDirectory
What i have:
an installscript.js (package root)
an ControlScript.js (path in config.xml)
What i tried in the ControlScript.js:
function Controller()
{
QMessageBox.information("DEBUG", "DEBUG", "DEBUG", QMessageBox.Ok);
installer.addWizardPage(component, "Start", QInstaller.Introduction);
QMessageBox.information("TEST", "TEST", "TEST", QMessageBox.Ok);
}
the Start.ui i placed at the config path and package root but nothing happens... the second MessageBox is never shown - the installer seems to be crashed
function Controller()
{
}
Controller.prototype.IntroductionPageCallback = function()
{
installer.addWizardPageItem(component ,"lineEdit",QInstaller.TargetDirectory);
}
same - nothing happens here installer crashed
hope you can help me to fix the code =)
and can someone please tell me how to change the language or setting a new pixmap (form an existing ressource) while the installer is running?
i wrote this incomplete code in installscript.js:
NewLanguageSeted = function()
{
var widget = gui.pageWidgetByObjectName("DynamicLanguageSelection");
QMessageBox.information("DEBUG", "DEBUG", "DEBUG", QMessageBox.Ok);
widget.Icon.setPixmap("");
installer.languageChanged();
QMessageBox.information("LanguageSelec", "LanguageSelec", "LanguageSelec", QMessageBox.Ok);
}
installer.languageChanged();
will Change all texts based on *.qm files - but how can i get / set the actual language?
widget.Icon.setPixmap("");
changes the pixmap - but i need to know what i have to insert in ""
for the ui file i use a resource file:
<property name="pixmap">
<pixmap resource="../../../resource/resource.qrc">:/DuerrPictures/watermark.png</pixmap>
As far as I know, installer pages canno't be added from the controller script. If you run the installer from QtCreator, you will see the corresponding debug output, which says something like component type is not defined.
To add the page you have to do it inside of the component script (e.g. the constructor). This one will be executed immediatly after you selected one of the 3 checkboxes. The .ui-file has to be part of the package, too:
Regarding the second linedit - It is the same problem! The function takes a component as argument - it has to be done inside the installscript.js.
installscript.js:
function Component()
{
QMessageBox.information("DEBUG", "DEBUG", "DEBUG", QMessageBox.Ok);
installer.addWizardPage(component, "Start", QInstaller.Introduction);
installer.addWizardPageItem(component ,"lineEdit",QInstaller.TargetDirectory);
QMessageBox.information("TEST", "TEST", "TEST", QMessageBox.Ok);
}
The pixmap should be settable by using the very same path you used in your .ui-file, i.e. :/DuerrPictures/watermark.png. Have your tried that?
And for your language problem - sorry, but I don't know anything about that. Check out the Scripting API - all script classes are listed there, maybe you can find something.

Is there a way to integrate handlebars-helpers with hapi?

I would like to use the handlebars-helpers node module with my handlebars templates. I'm using hapi as my framework which supports handlebars. I haven't found any documentation or examples that shows how to use handlebars-helpers with hapi using handlebars as the view engine.
Is it possible and if so, what is the solution?
after start hapi server
// hapi v17
try {
await server.start();
} catch (err) {
throw err;
}
//......
// add some handlebars helpers
let hbs = server.realm.plugins.vision.manager._engines.hbs;
// console.log('handlebars_helpers', handlebars_helpers);
if (handlebars_helpers) {
for (let key in handlebars_helpers) {
if (key) {
// console.log('key', key, helpers[key]);
hbs.module.helpers[key] = handlebars_helpers[key];
}
}
}
//check your helper is registered
// console.log('hbs.module.helpers', hbs.module.helpers);
// add some handlebars helpers
I don't think it's currently possible according to hapijs api docs for views:
http://hapijs.com/api#serverviewsoptions
helpersPath - the directory path where helpers are located. Helpers are functions used within templates to perform transformations and other data manipulations using the template context or other inputs. Each '.js' file in the helpers directory is loaded and the file name is used as the helper name. The files must export a single method with the signature function(context) and return a string. Sub-folders are not supported and are ignored. Defaults to no helpers support (empty path). Note that jade does not support loading helpers this way.
Looks as though handlebars-helpers has a different signature than what is required by hapi

Using modules in Meteor.js with Typescript

Folks, I'm trying to do something that I thought ought to be simple, but I must be doing something wrong. I'm trying to simply have a clear structure in my meteor application which uses Typescript.
Here are my requirements:
All interfaces are available in both client and server
Some class implementations are only available on the server
I don't want to rely on file load order for my application to work properly
I need my own module to not clash with global objects (such as the Position class for example)
I need to have one monolithic include file for server, one for both client and server and one for client (don't want to have 10s of includes on top of my files)
The setup that I have right now is this
server
server-book.ts
client
shared
collections.ts
definitions
server
include.d.ts (includes all .d.ts files in this folder)
server-book.d.ts (server specific implementation of book)
client
shared
include.d.ts (includes all .d.ts files here)
book.d.ts (book interface definition)
collections.d.ts
In each .d.ts file I have
module MyModule {
interface Bla {}
};
In each .ts file that defines a class I have:
module MyModule {
export class MyBla implements Bla {};
}
All .d.ts files generated for classes are generated by tsc -d.
No .ts files are being included via ///<reference> rather only .d.ts files.
Now, when I run this, I get an error that MyModule is undefined:
/// <reference path="shared/include.d.ts"/>
/// <reference path="server/include.d.ts"/>
Meteor.startup(() => {
var temp = new MyModule.ServerBook();
});
The error occurs right on MyModule.
What am I doing wrong? What should be the proper setup here?
Thanks!
I have dealt with this issue on my blog. I decided to use the evil eval command, since it gave me the easiest possibility of using modules till something more sophisticated appears.
File /lib/foo.ts is position in the subdirectory since it has to be loaded before Bar.
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Foo {
foo():string {
return 'foo'
}
}
}
File /bar.ts
/// <reference path="lib/foo.ts"/>
eval('var Hugo = (this.Hugo || (this.Hugo = {})'); // this will override the automatically emitted var Hugo and assigns it with globally defined Hugo module
module Hugo {
export class Bar extends Foo {
bar () : string {
return 'bar';
}
}
}
File /test.ts
/// <reference path="lib/foo.ts"/>
/// <reference path="bar.ts"/>
var m = new Hugo.Bar();
console.log(m.bar());
console.log(m.foo());
As mentioned here, for classes, the solution is even simpler:
class ExportedClass {
variable : int;
}
this.ExportedClass = ExportedClass;
Definition files should use the declare keyword. You would normally get an error if you didn't use this keyword.
declare module MyModule {
export interface Bla {}
}
And
declare module MyModule {
export class MyBla implements Bla {
}
}
It is also worth checking that the ServerBook class has the export keyword (just like MyBla in your examples).
After lot of trial and errors, here are my findings so far :
Using typescript "module" keyword doesn't get well with Meteor. I think at the moment you cannot use it (or the workarounds are too complicated for me).
However, here is what you can do :
Let say that you have package A where you want to define a class ClassToExport which you want to make public.
class ClassToExport {
getFoo(){
return "foo";
}
}
Please note that you can't write this.ClassToExport = ClassToExport and
api.export('ClassToExport') or else ClassToExport won't be available in the global scope of package A, hence the need for a module/namespace for exporting your class, which we will see next.
Now, for the class to be available for the consumers of your package, you have to create a namespace, which will be the equivalent of the "module" typescript keyword for internal module.
So let's write :
declare var packageA; //so that the compiler doesn't complain about undeclared var
packageA = packageA || {}; //so that this namespace can be reused for the entire package
packageA.ClassToExport = ClassToExport; //the actual export
Now, don't forget to write
api.export('packageA') in the package.js of package A
If you have a package B where you want to use ClassToExport, you write in package B:
var cte = new packageA.ClassToExport();
without forgetting to api.use package A in package B's package.js
If you don't want to write the namespace each time you use the class, you can also write var ClassToExport = packageA.ClassToExport; at the top of your using file.
If you need a global class for you package only, without exporting it, then you can do instead just :
this.ClassToExport = ClassToExport
and again don't write api.export('ClassToExport'), or it won't be available in the package anymore.
This way, i think the features (export/ import) of internal typescript modules are there.
If you are not afraid of gulp build, I have prepared a typescript boilerplate project which allows you to comfortably use typescript from within your app, not depending on packages.
https://github.com/tomitrescak/meteor-boilerplate-typescript
Random idea, what about extend Meteor instead of Window.
Meteor.yournamespace = Meteor.yournamespace || {};
Meteor.yournamespace.myclass = new MyClass();
or
Meteor.yournamespace.MyClass = MyClass();
I think this is less invasive than go directly to the window object IMHO. my two cents.
now you can do Meteor.yournamespace.MyClass :P
--EDIT
Then you could create a meteor-extend.d.ts file and do something like:
/// <reference path="main.d.ts" />
declare module Meteor {
var yournamespace: any;
}
Now you can remove the <any> before Meteor and Typescript will not complaint.

Gruntjs: Loading config files based on target

I'd like to be able to run the same builds for different targets by passing in config information from a build file, e.g. grunt build:target1 and grunt build:target2...
I figured I could access the target within the grunt file
module.exports = function ( grunt ) {
var userConfig = require( **'./'+grunt.task.current.name+'build.config.js'** );
var taskConfig...
grunt.initConfig( grunt.util._.extend( userConfig, taskConfig ) );
But the target is only available within a task.
Is there another way of accomplishing something like this?
You can pass command line arguments to Grunt by passing them using two dashes, like
--[your_arg_name]=[arg_value].
Example:
grunt --target=debug
Then retrieve this value in your Grunt config file by calling
module.exports = function (grunt) {
var target = grunt.option('target'),
userConfig = require('./' + target + "build.config.js");
...
}
You can choose whichever name you like, I chose target in my examples above.

Resources