How to properly import namespaced code used in Webpack/es6/babel? - javascript

I'm currently working on a ReactJS project and I'm trying to come up with an effective way to namespace my code. The most obvious solution I have is to do the following:
let API = {
init: function() {
// Do some type of initialization here
}
makeACall: function() {
// Make a call
}
};
Previously, I'd make a file of functions each of which were exported like:
export function makeACall() {
// Make a call
}
And then I'd import it into another file using: import { makeACall } from 'utils/api';
However the problem here is that I may have another function in the imported file called makeACall. So what I'd like to do is namespace it. Question is: how do I import individual functions from an object/namespace or is this not possible?

Related

Where should I put a 3rd js function and how to use it in .vue file?

In my vue app, I used a 3rd single js file contains a function, say getXXX looks like
(function(){function e(b,e,f)......&(window.getXXX=e)})();
I use this getXXX in my A.vue, if I just put this function inside A.vue, it works fine.
Now I'm thinking to put this long function to a single file, Where should I put a 3rd js function and how to use it in .vue file?
You can write a function in the another single js file. And export that function like this,
single-js-file.js which contains your function
export const getXXX = () => {
console.log('that works!');
}
And you can import it in the A.vue file like this,
import {getXXX} from './path-to-that-single-js-file'
And you can call that function in any of the life cycle hook in Vue
created() {
getXXX();
},
I would rather create a plugin for that (https://v2.vuejs.org/v2/guide/plugins.html), to be more specific about my approach, you can import this javascript file in your html entry point, this will expose the API of this library to the windows object in the client, while you can use window.xxx is not a clean solution, so you can create a wrapper in the form of a plugin and just return the instance of this library as a global object.
Hope this helps,
Cheers.

Write global functions to use in all components in angular

Note : Its not for global variable but for a global common function to perform a functionality on all components
I am working on an angular app where I have around 400 components in different modules, almost all components have one same kind of functionality as mentioned below
There is a sections on many pages which shows a "How to work section" which can be closed by users and will remain closed unless they open it again, I have done it with cookies which I set on click on close or open icon but this function is written in a component and this needs to be imported in other components
I want to create a functions somewhere which perform this functionality on click on icon and can be called without importing any component in others.
One way to do it ( as I thought ) could be create a JavaScript function in a file and load it in index file and then call this function on click on close and open icon
Not sure if this is the best way to do this. Hope someone will come up with a better solution.
1. create your global function service, i.e. 'funcs.services.ts' under 'services' directory:
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class FuncsService {
constructor() { }
myGlobalAddFunction(a){
return a++;
}
mySecondFunc(){
// add more... and so on
}
}
2. Import the function in your component:
// your path may different
import { FuncsService } from './../services/funcs/funcs.service';
//...
constructor(
private funcs: FuncsService
) {}
ngOnInit(): void {
let x = 1;
myResult = this.funcs.myGlobalAddFunction(x);
// Then you are expecting 2 for return value
}
3. Hope that works... :)
You can export a function that is a written in .ts file and then call it in all your components.
export function myFunction(){
// Do something
}
And then import the function myFunction() in other components. That works fine for me and can be useful in certain cases
This isn't the best solution (in my opinion). The best solution would be to either create a service, or an utils class.
But if you want to do this, I suggest you make a JS file, that you declare in your angular-cli.json file under the scripts property, containing your functions.
EDIT Now that you've came back to reason, here is a code sample to make utils classes.
export const IMG_UTILS = {
convertPngToJpg = (picture: any) => {
// Your logic here
}
};
export const VIEW_MANAGER = {
isAdblockActive = () => {
// test if an ad-blocker is active
}
};
You can make any utils class you want in a const, then put it into a file. Then, you can put this file in an utils folder, and request it with
import { VIEW_MANAGER } from 'src/app/utils/view-manager';
Otherwise, you can make a service, which is handled by Angular, with a console command such as
ng g s services/view-manager/view-manager
And it will behave the exact same way : you will import it in your components to use it.
Hope this helps !
The most recommended way is to use a service and inject it whenever needed, but there is a way to have a function available globally.
Although I don't think it's a really good idea, you can add the function in the index.html file, then whenever you want to use it, you have to use #ts-ignore to avoid an error from being thrown.
e.g
index.html
<script>
function globalFunc(){
alert(2)
}
</script>
anywhere else on the app
// #ts-ignore
globalFunc();
List item
Just to chime in with possibly a duplicate answer albeit more fleshed out... I have a utilities class which I use.
For example:
export class Utilities {
// Simple promise wrapper for setTimeout. See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises#creating_a_promise_around_an_old_callback_api
public static Wait = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms));
}
The class is referenced in a component via the import statement:
import { Utilities } from 'path/to/Utilities';
And then you can call your static methods thus:
Utilities.Wait(30000)
.then(() => DoStuff())
.catch(() => console.log('Darn!'));
I would tend to use RxJs but I've written it this way to keep things a little cleaner.

Angular 4 component : call javascript/jquery code from another file

i have a jquery code which gets executed at ngAfterViewInit()
//myComponent.ts
ngAfterViewInit() {
$(function () {
$('#myElement').click(function (e) {
//code working fine here
});
}
but i want to move it to an external myScripts.js to simplify the component
i tried moving tthe code to an external file then use import but this makes the script to be called only once so if i navigate to a child component (which erases the html element myElement with the onclick defined ) then back to the parent myElement is back without the onclick event
so the question is :
what is the best practice to use jquery/javascript with angular4
You need to export your function from myScripts.ts and then import it and call it within ngAfterViewInit().
After exporting correctly you should be able to do:
// app.ts
import { myInitFunc } from './myScripts';
ngAfterViewInit() {
myInitFunc();
}
// myScripts.ts
export function myInitFunc(): void {
$(function () {
$('#myElement').click(function (e) {
//do stuff
});
}
};
Take a look at export: https://developer.mozilla.org/en/docs/web/javascript/reference/statements/export

Patch/mock function inside another function for testing in javascript

Basically I'd like to patch functions that another function calls so that I can confirm they've been called. Is this possible in js? (I'm using Mocha/Chai/Sinon for testing).
A simplified version of what I'd like to do:
// in render.js
export helper = function() {}
export default = function() {
helper()
}
// in the render-test.js
import render, { helper } from 'render'
// what I'd like to to:
helper = sinon.spy()
render()
assert(helper.called, true)
It's possible, but it does require some rewriting, most notably the way you're calling helper in render.js.
Here's an example that works:
// render.js
export function helper() {}
export default function() {
exports.helper()
}
// render-test.js
import render, * as renderFuncs from 'render'
...
sinon.spy(renderFuncs, 'helper');
render()
assert(renderFuncs.helper.called)
The reason you need to call exports.helper() instead of just helper() is because the latter is a local reference to the helper function, which you can't access from the test file.
The exports object is accessible from the test file (it's given the name renderFuncs), so Sinon can change the reference to helper and wrap it with a spy.

Call a Aurelia function from <script>

In my Aurelia view I have a script tag from where I want to call a function from my view-model:
Page.html:
<template>
...
<script>
function beginEdit(args) {
console.log(args);
console.log(args.primaryKeyValue);
//In this place I want to call the sayHello() fuction
};
</script>
</template>
Page.js:
import {inject} from 'aurelia-framework'
import {HttpClient} from 'aurelia-http-client';
import {Router} from 'aurelia-router';
export class Licigrid{
constructor(){...}
activate(){...}
...
sayHello()
{
alert("Hello");
}
}
I tried to use inside my script tag ${sayHello();} but this calls the function immidiately when the page has loaded and not when the user has entered in the beginEdit() function.
I have reproduced this piece of code in Plunker.
Note that I am using a package that calls the beginEdit function by itself, so unfortunately I can not use .trigger(), .delegate(), or .call() inside my html tag which would solve my problem.
My question is: is there a solution to call the sayHello() function from my script tag?
The beginEdit function needs access to the App view model instance. We can use Aurelia's DI container to retrieve this:
var app = container.get(App);
app.sayHello();
Problem is we don't have access to the container within the beginEdit function. We can use a small hack to access the container:
var container = document.body.aurelia.container;
We also need the App constructor function because it's the key to retrieving the app instance from the container. We can use the System loader to load the module containing the App constructor function:
System.import('app').then(function(module) {
var App = module.App;
});
All together it looks like this:
function beginEdit() {
System.import('app').then(function(module) {
var App = module.App, // get the constructor function
container = document.body.aurelia.container, // get the container
app = container.get(App); // get the instance of App (the viewmodel)
app.sayHello();
});
}
Here's the working plunkr:
http://plnkr.co/edit/9c0oJmifjW5pXXdD06Hg?p=preview

Categories

Resources