how to make a js function public in angular 5 - javascript

I'm using Angular 5 to develop my application.
In assets/js folder, I have a js file test.js. I have a variable data and a function Loaddata() in this js file. I want to be able to access these in my app.component.ts.
I was able to make the variable scope public and was able to access it in component.ts, but I failed to do the same with the function.
This is the process I followed for the variable:
1. Add reference of js file in angular-cli.json
"scripts": [
"assets/js/test.js"
]
2. Added the variable name in typings.d.ts file.
declare var data:any;
Now I was able to access this variable in app.component.ts.
I want to be able to access even the function in the similar manner.
Can anyone explain me how to do it.

This seems like an awesome use case for using an Injectable Service. Create a loadData.service.ts file in the src/app directory of your application(if you are using Angular CLI), and then format it like this.
import { Injectable } from '#angular/core';
#Injectable()
export class LoadDataService {
data = [
// Your Data Here
]
constructor() {};
loadData(params?) {
// your code here
}
}
Then, whenever you need to use that function in a component, just import the service into your component, create a local instance of it in your constructor, and then use it!
To access the data, just set it equal to another variable in that components constructor.
import { LoadDataService } from '../loadData.service';
#Component({
//whatever
})
export class YourComponent {
dataFromService: [];
constructor(private loadDataService: LoadDataService) {
this.dataFromService = this.loadDataService.data;
}
runThisToGetData() {
this.loadDataService.loadData(yourParams).subscribe(r => r);
}
}
Best of luck!

Take a look at: https://nodejs.org/api/modules.html
You could just use exports to do what you are asking for.
foo.js
module.exports = {
hello: () => alert('hello from foo!')
};
EDIT ---- Fixed syntax
bar.js
const foo = require('./foo.js');
foo.hello();

Related

Scope import for an instance only

Good evening to everyone.
I'm not sure how can I explain my issue. I will show it to you by showing examples of the code and expected results. I could not use code from the real issue because the code is under license. I am very sorry for that and I will be glad of someone can help me solve my issue.
I'm using latest version of webpack, babel.
My application is spliced to three parts what are dynamically imported by each other. It is mean if I run split chunks plugin it will really create three clear files.
The parts are Core, Shared, Application. Where the Core only creating an instance of the application.
Result of the parts is bundled to single file. So it is linked by one html's script tag.
Project structure is:
src/app // For Application
src/core // For Core
src/shared // For Shared
In webpack configuration I am resolving alias for import ˙Editor$˙.
I renamed naming of variables because they are including project name.
resolve: {
alias: {
"Editor$": path.resolve('./src/app/statics/Editor.js'),
}
},
The content of Core file is
function createInstance(name, id) {
import("app").then(App => {
App(name, id)
});
}
The little bit of Application file is
imports...
import Framework from "./framework"
function createApp(name, id) {
new Framework({name, id}).$mount(...)
}
export default createApp
In the Application classes (what are instantiated inside Framework)
Is this import
import Editor from "Editor"
The Editor class is a singleton. But only for created instance.
class Editor {
static instance;
id = null;
constructor(){
if(this.constructor.instance){
return this.constructor.instance
}
this.constructor.instance = this
}
static get Instance() {
return this.instance || (this.instance = new this())
}
static get Id {
return this.Instance.id;
}
}
export default Editor
The issue is webpack dependency resolving. Because webpack puts and unify all imports to the top of the file.
So the imports are evaluated once through the life-cycle of the program.
But I need to tell webpack something like: There is an instance creation. Declare the new Editor singleton for this scope. Don not use the already cached one.
My another idea how to fix this is to set context for the instance. And in the Editor singleton create something like new Map<Context, Editor> if you get what I mean. But I did not find a way how to set a context for an instance or scope the import only for it.
I will appreciate any help. I am googling two days and still no have idea how to do it without rewriting all the imports.
Sorry for bugs in my English. I am not native speaker and my brain is not for languages.
Thanks everyone who take look into my issue.
How about recreating the Editor:
// Editor.js
class Editor {
// ...
}
let instance;
export function scope(cb) {
instance = new Editor();
cb();
instance = null;
}
export default function createEditor() {
if(!instance) throw Error("Editor created out of scope!");
return instance;
}
That way you can easily set up different scopes:
// index.js
import {scope} from "./editor";
scope(() => {
require("A");
require("B");
});
scope(() => {
require("C");
});
// A
import Editor from "./editor";
(new Editor()).sth = 1;
// B
import Editor from "./editor";
console.log((new Editor()).sth); // 1
// C
import Editor from "./editor";
console.log((new Editor()).sth); // undefined
// note that this will fail:
setTimeout(() => {
new Editor(); // error: Editor created out of scope
}, 0);
That also works for nested requires and imports as long as they are not dynamic.

How to use methods from external js in Angular

I need to call a function from external js file into my Angular component
I already go through the related question
How can i import external js file in Angular 5?
How to include external js file in Angular 4 and call function from angular to js
My External JS (external.js)
var radius = 25;
function calculateRadius(pi) {
let piValue = 3.14159;
if(pi) {
piValue = pi;
}
var result = piValue * radius * radius;
console.log('Result: ', result);
}
function wrapperMethod(pi) {
console.log('Hi, this is from wrapper method');
calculateRadius(pi)
}
I added the said JS file in the angular.json under scripts block
"scripts": [
"src/assets/external.js",
]
In the CircleComponent, I would like to call the method
import wrapperMethod from '../../src/assets/external.js';
#Component({
selector: 'app-circle',
templateUrl: './circle.component.html',
styleUrls: ['./circle.component.css']
})
export class CircleComponent implements OnInit {
constructor() { }
ngOnInit() {
wrapperMethod(3.14159);
}
}
But its failing to call the method. Kindly assist me how to achieve this.
Note: The said methods as just an example methods, I want to implement this logic with the complex code file. The said question tells about typings.d.ts, but I don't know where is typings.d.ts in my Angular project. Kindly brief me regarding this. If the said question gives good solution means, why should I post this question.
Angular Structure (Created using Angular CLI)
I don't know where is typings.d.ts, could anyone please tell me where is typings.d.ts - which is mentioned in the said questions How to include external js file in Angular 4 and call function from angular to js
You can follow this below steps
1) First add a reference of your external JS file for importing it to the component.
import * as wrapperMethods from '../../src/assets/external.js';
2) Now declare a "var" of the same name that your function has inside external JS.
declare var wrapperMethods: any;
3) ngOninit(){
wrapperMethods();
}
put your external .js file under scripts in build
if still can not see methods inside it put in in index.html
<script src="assets/PATH_TO_YOUR_JS_FILE"></script>
in your component after import section
declare var FUNCTION_NAME: any;
ANY_FUNCTION() {
FUNCTION_NAME(params);
}
Don't get confused with typings.d.ts. Follow below steps.
1.Add your external file inside assets folder. The content of this file will be by default included as per your angular-cli.json.
2.The function of your js which you're going to use must be exported. i.e.
export function hello() {
console.log('hi');
}
3.Import your file inside your component as below.
import * as ext from '../assets/some-external.js';
4.Now you can reference it like
ext.hello();
Steps:-
1. create a external js file.
2. In component.ts use the below code.
ngOnInit() {
this.loadJsFile(JsFilePath);
}
public loadJsFile(url) {
let node = document.createElement('script');
node.src = url;
node.type = 'text/javascript';
document.getElementsByTagName('head')[0].appendChild(node);
}
3. If u use jquery then define selector in html to render. Or store data in variable.
Make sure you have to add jquery cdn in index.html and you have to install Jquery and its types package from npm.

ES6 import issue

I am creating a Single page application base on MVC, and I am stuck with a small issue. I am exporting the reference of controller class and I am importing it at a few places and it is working fine but when I am trying to import it into a specific file, it's not working, I spent a lot of time, but couldn't figure it out. I am sure I am missing some obvious thing. Here is my code(Link to Repo for more details):
Controller(Actual File):
class Controller extends Base {
constructor(){
super()
//more code
}
//more code
static create() {
return new Controller() // planning to make a singleton later on
}
}
const controller = Controller.create()
export default controller
Model(import works in this one, Actual file):
import controller from '$js/Controller'
export default class Model {
... Model code
static fxn(){
controller.controllerFunction()
}
}
Utils File(import doesn't work in this file, Actual File):
import controller from '$js/Controller'
export function someFunction(args) {
const value = controller.get() // Throws an error saying `controller` is not defined
}
Here is the Github Repo link. Please let me know if you need anything else.

Migrating a JavaScript\Ionic\Angular 1 App to Typescript\Ionic 2\Angular 2 App

I'm working on migrating an App from JavaScript\Ionic\Angular1 to Typescript\Ionic2\Angular2 one file at a time. I've poured over dozens of how-to's and such about migrating from one to the other, done the Angular 2 quick start and tutorial, and seen how to go from .js to .ts as well as installed all of the npm packages I need. Assuming I have everything I need to start the migration process, I really need help actually starting. I have dozens of files to convert, and it would help me greatly to just get one file converted correctly with the old code commented out to use as a reference to convert the others.
Here is a sample file. If you could convert this for me, or walk me through converting it, I would be very appreciative.
angular.module('myApp.app', ['ionic'])
.controller('myApp.app', function($rootScope, $scope, AService, BService, CService){
$scope.setUserName = function (user){
$scope.user = user;
};
document.addEventListener('deviceready', function() {
$rootScope.$on('$cordovaNetwork:online', function (e, nState) {
BService.setOnline(true);
})
})
})
Thank you.
The code below is not complete, but gives you an idea of the direction you should be heading. It is a modified version of the boilerplate code that is created for you whenever you use the ionic-cli to generate a new app.
You would define your services each in a separate file in a subfolder of your app/ folder called services. For example, your AService would be defined in app/services/a-service.ts. You import app level services at the top of your app.ts file and then include them in an array as the second component to the ionicBootstrap() function at the very bottom of the file. You also have to inject them as private variables in the constructor() of your MyApp component.
There is no longer anything like a $scope or $rootScope where you can store app-wide variables. Instead, you would create a provider (e.g. UserData) that you would use to store data that needs to be persisted across pages or sessions.
I recommend reading through the Ionic 2 Conference Application, which has been developed as a sample app using the Ionic 2 framework by its developers. It shows you how to handle things like user login, and persisting data across the app.
import { Component } from "#angular/core";
import { ionicBootstrap, Platform, Nav } from "ionic-angular";
import { AService } from "./services/a-service";
import { BService } from "./services/b-service";
import { CService } from "./services/c-service";
import { UserData } from "./providers/user-data";
import { HomePage } from "./pages/home/home";
#Component({
templateUrl: "build/app.html"
})
export class MyApp {
// the root nav is a child of the root app component
// #ViewChild(Nav) gets a reference to the app's root nav
#ViewChild(Nav) nav: Nav;
rootPage: any = HomePage;
pages: Array<{ title: string, component: any }>;
constructor(
private platform: Platform,
private aSvc: AService,
private bSvc: BService,
private cSvc: CService,
private userData: UserData
) {
this.initializeApp();
// array of pages in your navigation
this.pages = [
{ title: "Home Page", component: HomePage }
];
}
initializeApp() {
this.platform.ready().then(() => {
// Okay, so the platform is ready and our plugins are available.
// Here you can do any higher level native things you might need.
bSvc.setOnline(true);
});
}
openPage(page) {
// Reset the content nav to have just this page
// we wouldn't want the back button to show in this scenario
this.nav.setRoot(page.component);
}
}
// Pass the main app component as the first argument
// Pass any providers for your app in the second argument
// Set any config for your app as the third argument:
// http://ionicframework.com/docs/v2/api/config/Config/
ionicBootstrap(MyApp, [AService, BService, CService, UserData]);

How to include external JavaScript libraries in Angular 2?

I am trying to include an external JS library in my Angular 2 app and trying to make all the methods in that JS file as a service in Angular 2 app.
For eg: lets say my JS file contains.
var hello = {
helloworld : function(){
console.log('helloworld');
},
gmorning : function(){
console.log('good morning');
}
}
So I am trying to use this JS file and reuse all the methods in this object and add it to a service, so that my service has public methods, which in turn calls this JS methods. I am trying to reuse the code, without reimplementing all the methods in my typescript based Angular 2 app. I am dependent on an external library, which I cant modify.
Please help, thank you in advance.
With ES6, you could export your variable:
export var hello = {
(...)
};
and import it like this into another module:
import {hello} from './hello-module';
assuming that the first module is located into the hello-module.js file and in the same folder than the second one. It's not necessary to have them in the same folder (you can do something like that: import {hello} from '../folder/hello-module';). What is important is that the folder is correctly handled by SystemJS (for example with the configuration in the packages block).
When using external libs which are loaded into the browser externally (e.g. by the index.html) you just need to say your services/component that it is defined via "declare" and then just use it. For example I recently used socket.io in my angular2 component:
import { Component, Input, Observable, AfterContentInit } from angular2/angular2';
import { Http } from 'angular2/http';
//needed to use socket.io! io is globally known by the browser!
declare var io:any;
#Component({
selector: 'my-weather-cmp',
template: `...`
})
export class WeatherComp implements AfterContentInit{
//the socket.io connection
public weather:any;
//the temperature stream as Observable
public temperature:Observable<number>;
//#Input() isn't set yet
constructor(public http: Http) {
const BASE_URL = 'ws://'+location.hostname+':'+location.port;
this.weather = io(BASE_URL+'/weather');
//log any messages from the message event of socket.io
this.weather.on('message', (data:any) =>{
console.log(data);
});
}
//#Input() is set now!
ngAfterContentInit():void {
//add Observable
this.temperature = Observable.fromEvent(this.weather, this.city);
}
}

Categories

Resources