Load JavaScript file in angular2 app - javascript

I'm working on a angular2 application written in TypeScript.
This works:
I have a module called plugin-map.ts which looks something like this:
import { Type } from '#angular/core';
import { SomeComponent } from './plugins/some.component';
export const PluginMap: { [key: string]: Type<any> } = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': SomeComponent
};
It gets transpiled to a plugin-map.js which looks something like this:
"use strict";
var some_component_1 = require('./plugins/some.component');
exports.PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
//# sourceMappingURL=plugin-map.js.map
And in other modules I'm importing my PluginMap like this:
import { PluginMap } from './plugin-map';
What I want:
Now I want to create plugin-map.js at runtime when my server starts. So I want to get rid of my plugin-map.ts and instead have only a (generated) plugin-map.js. And I don't want to have any transpile-time dependencies to that plugin-map.js.
What I tried:
In modules where I need to access the PluginMap I replaced the import statement with a declaration like this:
declare const PluginMap: { [key: string]: Type<any> };
Now of course at runtime I get a Error: (SystemJS) 'PluginMap' is undefined. So my next step was to load plugin-map.js explicitly from my index.html like this:
...
<script src="js/system.src.js"></script>
<script src="systemjs.config.js"></script>
<script>
System.import('./app/plugins/plugin-map.js').catch(function (err) { console.error(err); });
System.import('app').catch(function(err){ console.error(err); });
</script>
...
When I start my application I can see that the browser actually requests the plugin-map.js file. But I still get the Error: (SystemJS) 'PluginMap' is undefined.
Question:
How/where do I have to load my generated plugin-map.js so that this works?

I had to make sure that PluginMap is available in the global context. So the generated plugin-map.js has to look like this:
var some_component_1 = require('./plugins/some.component');
PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
and not like this:
"use strict";
var some_component_1 = require('./plugins/some.component');
exports.PluginMap = {
'e690bec6-f8d1-46a5-abc4-ed784e4f0058': some_component_1.SomeComponent
};
//# sourceMappingURL=plugin-map.js.map
Now it seems to work.

Related

BackEndUrl is undefined

I created a plugin, which should post some data to my backend. I tried to set up some backend url config. I checked the URl within my plugin with "console.log(...)" as u can see withn my code (in sendDataToBackEnd.js). But i getting following output "undefined".This is the error: "Error message: Cannot read property 'backEndUrl' of null"
Project structure:
project1
public
backend-config.js
faviocon.ico
index.html
src
App.vue
main.js
config
backEndUrlConfig.js
plugin
sendDataToBackEnd.js
Therefore I created backend-config.js within in Folder "public"
(function (window) {
window._backendconfig = {
urlBackend: `http://localhost:8090/api/auth/event`,
}
}(this));
My config.js looks like this:
export default { ...window._backendconfig }
And my PLugin "sendDataToBackEnd.js" looks like this:
import url from '../../config/backendURLconfig';
var backEndUrl = url.urlBackend;
console.log(backEndUrl)
const sendDatatoBackEnd = {}
sendDataToBackEnd.install = function (Vue){
{Method to send Data to my Backend}
}
export default sendDatatoBackEnd;
You're mixing using global scope JS (setting a property on window) in your config file with module style JS in your sendDataToBackEnd.js file (importing and exporting from modules).
You either need to export something from config (best option if you're using modules), or just access it from the window.
backendURLconfig.js
const config = {
urlBackend: `http://localhost:8090/api/auth/event`,
}
export default config
sendDataToBackEnd.js
import config from '../config/backendURLconfig';
var backEndUrl = config.urlBackend;
console.log(backEndUrl)
const sendDatatoBackEnd = {}
vuePlugin.install = function (Vue){
{Method to send Data to my Backend}
}
export default sendDatatoBackEnd;

Packaging JavaScript Functions

I'm working to create a shared package of JavaScript functions. At this time, I'm trying to use them like this:
/app/index.js
const myPackage = require('../myPackage');
myPackage.function1();
myPackage.myScope.function2();
The above successfully loads myPackage. However, when I attempt to run function1, I receive an error that says: "TypeError: myPackage.function1 is not a function". My code in the "package" is organized like this:
/myPackage
index.js
root
function1.js
myScope
function2.js
The code looks like this:
index.js
require('./root/function1.js');
require('./myScope/function2.js');
function1.js
exports.function1 = function() {
console.log("Doing stuff in function1");
}
function2.js
exports.function2 = function() {
console.log("Doing stuff for function2");
}
I could understand function2 not working because, there's nothing putting it in myScope, which I don't know how to do. However, I don't understand why function1 isn't running. What am I doing wrong?
To elaborate bergi's answer, you need to have the following in your index.js file:
// file: index.js
exports.function1 = require('./root/function1.js').function1;
exports.myScope2 = {
function2: require('./myScope/function2.js').function2,
};
Because require('./root/function1.js') == exports object in function1.js. So if you
have multiple functions in your function1.js, you have to go like this:
// file: index.js
exports.function1 = require('./root/function1.js').function1;
exports.function11 = require('./root/function1.js').function11;
exports.function111 = require('./root/function1.js').function111;
...
A shortcut of that can be:
// file: index.js
Object.assign(exports, require('./root/function1.js'));
On the other hand: you can set the exports object to be your function:
// file: function1.js
module.exports = function() {
console.log("Doing stuff in function1");
}
Then you can have the following in your index.js file:
// file: index.js
exports.function1 = require('./root/function1.js');
exports.myScope2 = {
function2: require('./myScope/function2.js'),
};
Here require('./root/function1.js') == function1 from function1.js. Hope that explains
the issue.
Your index.js doesn't export anything. You will have to do
Object.assign(exports, require('./root/function1.js'));
exports.myScope = require('./myScope/function2.js');
Or maybe better have your function1.js and function2.js modules export the function itself (module.exports = function() { … };) instead of creating a property, then use
exports.function1 = require('./root/function1.js');
exports.myScope = {
function2: require('./myScope/function2.js'),
};

Webpack 4: How to call a global function with arguments?

I'm writing a new build script for my project using Webpack 4, so far, I have not faced any issue until today, when I have to call a global function with parameters.
Below is an example, I did without parameters for Google reCaptcha:
const enableFormButton = () => {
var elements = "#form_submit_btn, #form_submit_btn_alt";
$(elements).removeAttr("disabled");
$(elements).css({"cursor":"pointer"});
$(elements).removeClass("button button-3d button-red button-small").addClass("button button-3d button-green-invert button-small");
}
const recaptcha = document.querySelectorAll(".g-recaptcha");
recaptcha.forEach((captcha) => {
captcha.setAttribute('data-callback', 'enableFormButton');
});
export { enableFormButton }
and in my entry index.js file, it would look like this:
import {enableFormButton} from './some_js_file'
window.enableFormButton = enableFormButton
Now, this is what I tried with a global function with parameters:
const exampleFunction = (arg1) => {
// do something here
}
export {exampleFunction}
and in the index.js file:
import {exampleFunction} from './some_js_file'
window.exampleFunction = exampleFunction
I tried it, there are no build errors but I get an error in the console saying
"Uncaught TypeError: exampleFunction is not a function"
Any idea on how to solve this? Btw, I'm kind of new to using Webpack.
Thanks to #CertainPerformance's tip, I added the export keyword to the function exampleFunction(arg1), which should look like this:
export exampleFunction(arg1){
// something
}
Imported the function to another .js file:
import {exampleFunction} from './somescript';
And then, it worked! :)
So turns out, I learnt something for the day!

How to use Vue Plugins Correctly? <PluginName> is not defined

Im learning to make Vue Plugin, based on https://v2.vuejs.org/v2/guide/plugins.html,
this is my simple code:
plugin1.js:
AlertPlugin.install = function (Vue, options) {
Vue.prototype.$classicalert = function (message) {
alert(message)
};
};
app.js:
window.Vue = require('vue');
import AlertPlugin from './plugin1.js'
Vue.use(AlertPlugin);
const app = new Vue({
el: '#app',
render: h => h(Main)
});
when im trying to run it, the web page become blank, and error AlertPlugin is not defined.
please help?
In your plugin1.js file, you are attempting to set the install property of the AlertPlugin object, which (as the error says) is not defined.
Your plugin1.js file should look like this:
export default {
install: function (Vue, options) {
Vue.prototype.$classicalert = function (message) {
alert(message)
};
}
}
This defines a default object to export containing a property install. When you import this object as AlertPlugin, like you are doing in app.js, it will result in an AlertPlugin object with the install property you defined in the plugin's file.

Function imported from a module in Typescript isn't recognised as a function in compiled JS?

I have a Typescript project, which calls a function from a module.js module. Here is my initial code:
//app.ts
import { MobileServiceUser, setCache, getCache } from "nativescript-azure-mobile-apps/user";
export function onLoginTap(args) {
console.log("tap");
ai.busy = true;
var cache = getCache();
}
if I use the VSCode "go to definition" feature, then getCache() goes to the import statement at the top, if I do this again, then I go to:
//module.ts
declare module "nativescript-azure-mobile-apps/user" {
export class MobileServiceUser {
mAuthenticationToken: string;
mUserId: string;
constructor(o: { userId: string; });
}
export function setCache(user: MobileServiceUser): void;
export function getCache(): MobileServiceUser;
}
When I execute the code and the var cache = user_1.getCache(); line is executed, my app crashes, throwing error:
TypeError: user_1.getCache is not a function
File: "/data/data/inc.tangra.azuremobileservicessample/files/app/main-page.js, line: 94, column: 23
app.ts looks like this compiled to js:
var user_1 = require("nativescript-azure-mobile-apps/user");
function onLoginTap(args) {
console.log("tap");
ai.busy = true;
var cache = user_1.getCache();
}
Why isn't the code recognising the imported function?
Update: this repo shows the project structure (the first page of code is in sample/main-page.ts

Categories

Resources