Calling JavaScript methods from typescript - javascript

Currently, I'm trying to use work with the online view of the document and I came across this website.https://rollmyfile.com/.
when I head towards the developer APIs https://rollapp.readme.io/v1.0/docs/rollmyfile-js-api. I find I can read any document by passing the URL. But I'm working on angular 4 which uses typescript so I did call out
so I placed the js code in my index.html
index.html
<script type="text/javascript" src="https://api.rollapp.com/1/js/rollmyfile.js"></script>
now I need to make use of this js file to pass the Url to it something this.
<script type="text/javascript">
var key = "SeCur3AP1K3y";
var rollMyFile = new RollMyFile(key);
</script>
rollMyFile.openFileByUrl("https://www.example.com/documentation/overview.docx");
so, I need to make use of .openFileByUrl in my .component.ts
I have referred the path as well in my .component.ts something like this
///<reference path="https://api.rollapp.com/1/js/rollmyfile.js"/>
but still, I'm not able to create an instance of RollMyFile.
I'm getting [ts] Cannot find name 'RollMyFile' error.
Is there something that I'm doing wrong?

You need to declare RollMyFile on top in order to use that function in your TS file
declare const RollMyFile: any;
ngOnInit() {
console.log("hi");
var key = "SeCur3AP1K3y";
var rollMyFile = new RollMyFile(key);
console.log('rollMyFile',rollMyFile)
}
This console giving me error because of having wrong secret key.

try this in your component :
declare RollMyFile: any;
constructor(private _script: ScriptLoaderService) {}
ngOnInit() {
this._script.load('body', 'https://api.rollapp.com/1/js/rollmyfile.js')
.then(result => {
});
}
}
and use RollMyFile in your code something like this:
(<any>RollMyFile).somfunction();

Related

When is the Blockly.Workspace being created?

I am trying to override certain functions in the Blockly API. I am working with react and use the react-blockly package. I am overriding the workspace class. My code looks exactly like in the official repo and I changed the createVariable to look like this:
Blockly.Workspace.prototype.createVariable = function (
name,
opt_type,
opt_id,
opt_length
) {
return this.variableMap_.createVariable(name, opt_type, opt_id, opt_length);
};
As you can see the function is using the variableMap_ which is getting instantiated when calling Blockly.Workspace:
Blockly.Workspace = function (opt_options) {
...
this.variableMap_ = new Blockly.VariableMap(this);
...
}
When I run my code Blockly.Workspace is never called and variableMap_ is undefined.
When I search where Blockly.Workspace is used in the official repo I am not able to find out where it is getting called:
Workspace extends Workspace__Class and is only mentioned in the compressed file and the workspace.js file.
So my question: When is Blockly.Workspace called and this.variableMap_ instantiated?

Can I allow dynamic loading of JS modules from the client side?

In my web app I want to give users the ability to author their own modules for use in the app. These are ideally written in JS on the client side.
However, I'm having trouble allowing for classes created on the client side to be accessed by the app. Originally I wanted some kind of module import, but dynamic imports still require a path, which isn't accessible by the browser for security reasons. Just doing a straight import of the JS into a script tag pollutes the global namespace, which isn't ideal either.
Is there some sensible way to do this? I would ideally want to import the class, e.g.
// MyClass.js, on the client side
export default class MyClass {
myPrint() {
console.log('ya blew it');
}
}
And then in App.js:
import(somehow_get_this_path).then((MyClass) => { etc});
Is getting that path possible? The current namespace-polluting method uses a select file dialog but doesn't allow me to tell import what path it has. All you get is a blob. I'm pretty new to this stuff so apologies if this question is dumb.
edit: I've tried getting an object URL using CreateObjectURL, which gives the error:
Error: Cannot find module 'blob:null/d651a896-d568-437f-86d0-72ebcee7bc56'
if you are using webpack as a bundler then use can use magic comments to lazy load the components.
or else you can use dynamic imports.
import('path_to_my_class').then(MyClass => {
// Do something with MyClass
});
Edited 1:-
You can use this code to get a working local URL for the uploaded js file. try using this
const path = (window.URL || window.webkitURL).createObjectURL(file);
console.log('path', path);
Edited 2:-
Alternatively, you can create your own object at a global level and wrap the file using an anonymous function (creating closure) such that it won't pollute the global namespace.
// you can add other methods to it according to your use case.
window.MyPlugins = {
plugins: [],
registerPlugin: function (plugin){
this.plugins.push(plugin);
}
}
// MyFirstPlugin.js
// you can inject this code via creating a script tag.
(function(w){ //closure
function MyFirstPlugin() {
this.myPrint = function (){
console.log('ya blew it');
}
}
w.MyPlugins.registerPlugin(new MyFirstPlugin());
})(window)
// get the reference to the plugin in some other file
window.MyPlugins.plugins
Read file and use eval
<script>
function importJS(event) {
var input = event.target;
var reader = new FileReader();
reader.onload = function(){
eval(reader.result);
input.value='';
};
reader.readAsText(input.files[0]);
};
</script>
Select a *.js file and execute
<br>
<br>
<input type="file" onchange="importJS(event);">

ReferenceError: [...] is not defined

I am trying to use a JS function which is in an another JS file and I have this error :
ReferenceError: Lanceur is not defined
Lanceur is my object which is defined in my second file.
I have a constructor :
public class Lanceur {
constructor(angleAiguille) {
this.angleAiguille = angleAiguille;
} // And functions .....
I have this line in my first file : lanceur = new Lanceur(0);
And I call my files in a HTML files with <script src="js/canvas.js" type="text/javascript"></script>, for example.
You need to create the class before you can create an instance of it. You also don't need the keyword public as browsers don't support it currently (Unless you're compiling this through Babel or something similar, but that wasn't obvious from your post).
In your first file include the code that makes up the class, I've added a method as an example.
class Lanceur {
constructor(angleAiguille) {
this.angleAiguille = angleAiguille;
}
someMethod() {
console.log('Firing')
}
}
You can then create an instance of it like so in your second file and call its methods.
const instance = new Lanceur;
// Calling a method...
instance.someMethod();
You can learn more about JavaScript class constructors here.

Javascript: usage of require in Appcelerator Titanium

I am quite new to javascript and I am struggling with a simple problem. I have to split up codes into separate files. As an example I have a file called Database.js. In that file I have the following lines:
function Database(){
//someStuff
this.fetchAll = function(){
//some stuff
return something;
}
}
Now I want to use the Database.js code in the file app.js. So I write the following code in app.js:
var Database = require('Database');
var myDB = new Database();
var result = myDB.fetchAll();
However, I get the error Script Error = '[object Database]' is not a constructor (evaluating 'new Database()') at app.js (line 3).
What is my mistake?
Before you moving to the development, you need to understand thoroughly about CommonJS Modules in Titanium. Then it will be more simple for you. Also refer the require function
Let's come to your error. [ERROR] [object Database]' is not a constructor (evaluating 'new Database()') at app.js (line 3) means that the module you created is not constructor. Your constructor function might not return any value. Read simple usage of CommonJS module. I'm sure it will resolve your issue.
There is an alternative way, you can include your Database.js file in your app.js. You does not need to return anything and no need to use require function. You just need to use the include method. Just write Ti.include('Database.js'); inside your app.js and you can access all the global variables and functions inside the Database.js file
This question is old but it has not been answered yet. So i will just provide the answer for anyone who is visiting here.
You have to export you function as global. To do so you would declare it as below
exports.fetchAll = function Database(){
//some stuff
return something;
};
You can also declare the function so that it can be used globally as well as locally within the file
var fetchAll = function Database(){
//some stuff
return something;
};
exports.fetchAll = fetchAll;
Then assuming the file name is Database and it is in same folder as app.js, you can use it as below
var Database = require('Database');
var result = Database.fetchAll();
edit: This answer is javascript general and it's not oriented towards Appacelerator Titanium.
There is no such include or require in javascript. You can on the other hand do one of the following
Include a script tag before your script to include Database.js
<script type="text/javascript" src="Database.js" >
OR
Add it dynamically
function loadScript(url, callback)
{
// adding the script tag to the head as suggested before
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
script.src = url;
// then bind the event to the callback function
// there are several events for cross browser compatibility
script.onreadystatechange = callback;
script.onload = callback;
// fire the loading
head.appendChild(script);
}
The problem seemed to be the usage of the variable name 'Database'. Maybe there is somewhere a name collusion.
I am sorry that I did not know that the usage of require is not a basic concept of js.
Just a quick guess here. If you use CommonJS then you have to tell what should be available outside of the module. The way you lay out that you have made the Database "object" you would need to add:
module.exports = Database;
somewhere in your module. I always put them at the end - but not sure that is a requirement.
You can also make individual functions available outside of a module by specifying:
exports.getMyDatabase = getMyDatabase;
Where "getMyDatabase" is a function you have specified in the module. I use this way to "hide" certain implementation details of some functions from the outside and just make available the functions I want the developer to be able to call ;-)
/John
I think this is the right usage of require js:
require(["Database"], function() {
var myDB = new Database();
var result = myDB.fetchAll();
});
http://requirejs.org/docs/jquery.html

RequireJS - pass parameters into module for initialization [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How to load bootstrapped models in Backbone.js while using AMD (require.js)
I am currently creating a RESTful API for one of our projects and also wanted to provide a Javascript library to access it.
Since I like the AMD principle and using require.js, I would provide an AMD module as well.
The problem is: the initialization of the module would require some information like the API key on initialization.
How do I pass such parameters into a module upon initalization?
If you have something like:
define(['dep1', 'dep2', 'dep3'], function (dep1, dep2, dep3) {
var module = {
...
};
return module;
});
change it to:
define(['dep1', 'dep2', 'dep3'], function (dep1, dep2, dep3) {
var module = {
...
};
var init = function (options) {
// Initialize here
return module;
};
return init;
});
Then after requiring your module somewhere, you can call it to initialize. You might also want to look into the factory pattern if you need something more complex and return the factory.
require.js does not restrict you in what you return. It can be a simple object, a string, a function...
I think what your looking for is the ability to set config variables that get picked up by the module. Here is an example using require.js
How to load bootstrapped models in Backbone.js while using AMD (require.js)
One other possibility that came to my mind is to use a serverside script to manipulate the source of the module when you are requesting it.
For example when you have to pass an API-key into the module, you do the following:
Before you do your first define() call, put the following code:
require.config({
paths: {
api: 'https://api.example.com/api.amd.js?api_key=f615ac61&'
}
});
This enables you to simply require your API from anywhere like this:
require(['api'], function(api){
});
So the server recieves the request - maps it thorugh mod_rewrite to some script, takes the GET parameter and puts it on the correct place in the module sourcecode, then returns the custom source.
Thats the way I solved this by now and it works like a charm, without the need to change any behaviour of the developers and it makes use of functionality thats already built into requirejs.
I don't think you can do that with require.js, but you can with Frame.js or some other module library. In Frame you would do that like this:
//moduleName.js
(function(exports){
exports.moduleName = function(args){
// do stuff
}
})(window.exports);
// in main js file
var exports = {}; // global variable
Frame('moduleName.js');
Frame(function(next){
var myArgs = { ... settings ... };
exports.moduleName(myArgs);
next();
});
Frame.init();
Is it possible to use a namespaced variable, and then to reference the appropriate object when you initialize the specific library? Maybe I don't understand exactly what you want require.js to do, but it looks like you call it from your main.js in any event, so I'm pretty sure it would work... I don't think you can do it like <script = "require.js?apiKey=jsdfhjkfklsjkfdjks">
var libData = {
apiKey: "jsdfhjkfklsjkfdjks",
otherpram: "userIDorsomething"
}
require(libData.apiKey);
but if you needed to send the apikey in the url parameter of the page, you could use a script like this to get the parameters:
<script>
function getQueryParams(qs) {
qs = qs.split("+").join(" ");
var params = {},
tokens,
re = /[?&]?([^=]+)=([^&]*)/g;
while (tokens = re.exec(qs)) {
params[decodeURIComponent(tokens[1])]
= decodeURIComponent(tokens[2]);
}
return params;
}
// assuming the page is loaded like page.html?apikey=jsdfhjkfklsjkfdjks
apiKey = getQueryParams(document.location.search).apiKey;
// however you have to call require, pass the api key?
</script>

Categories