How can I call a function of an exported function of a module in another script? NodeJS - node.js

I want to use a function, which is inside another function (function2) in another js file (2nd.js).
My current code looks something like this:
1st.js
module.exports = {
function1(){
function2(){
//...
}
}
}
2nd.js
const { function2 } = require("1st.js")
function2()
This sadly doesn't work and I have no idea how to solve this problem.

You can work with class approach or some older syntax. Any of these approaches results in the same thing, after all, the class syntax in JavaScript is just a thing for programmers, and does not affect the code at all. It is called syntax sugar.
See in the example below how to solve your problem without classes:
Export a object "container" with your functions:
Just as you referred in your example, 1st.js
export default {
functionOne: () => {
console.log("one");
},
functionTwo: (num) => {
console.log(num);
},
functionThree: ({number}) => {
console.log(number);
},
}
And import it with any name you want
...and so on, 2nd.js
import myFunctions from "../myFunctions";
const { functionOne, functionTwo, functionThree} = myFunctions;
functionOne();
functionTwo("two");
functionThree({number: "three"});

Related

How do I test a function that is in a class with Jest

I have a function that is in a class :
Simplified version :
export class Button {
getAttributes(el) {
//random code that was removed for simplicity
return dataAttrs;
}
}
I was wondering how do I test this in Jest.
Here is what worked for me :
test('get attributes on element', () => {
let button= new Button();
var element = document.createElement('a');
element.setAttribute('href', 'https://www.google.ca/');
element.innerHTML = 'Test';
expect(breadcrumb.getAttributes(element)).toBe('Hello');
});
if there is simple class like the one that u define u can do:
it('We can check the class constructor', () => {
const classObject = new classObject();
expect(classObject ).toHaveBeenCalledTimes(1);
});
and use whatever the methods that Jest have.
But if there are complex classes and methods that ones are dependent from others i suggest you to read this and you can automatize it or can do it manually, mock the dependences and test it out.

React-native and Redux healthy way to call actions on props change

I've been using react-native with redux for a while, and the way i learn to call actions when something change on prop is using the componentWillReceiveProps, but when I use it I need to pass between if's and some times it goes to the wrong if, then I need to add more stuff to prevent it.
Here's an example I have done. I know this is not the best way to do it, but it is what I could think of.
componentWillReceiveProps(newProps) {
if(Object.keys(newProps.selected_product).length > 0) {
if(Object.keys(this.props.current_location).length > 0 || Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
this.props.verifyProductById(newProps.selected_product, newProps.current_location, this.props.token);
} else {
this.props.statusScanner(false);
this._handleNextPage(1);
}
} else if(Object.keys(newProps.historic_product_confirm).length > 0) {
if(newProps.historic_product_confirm.location._id == newProps.current_location._id)
this.props.handleModalConfirmPrice(!this.props.modal_confirmPrice_status)
} else if(newProps.scanResult != "") {
this.props.statusScanner(false);
if(Object.keys(newProps.current_location).length > 0) {
this._handleNextPage(2);
} else {
this._handleNextPage(1);
}
} else {
this._handleNextPage(0);
}
}
What I need is a healthy way to call my actions when the props change.
Edit:
Here i have the full OfferScene and an action file example:
OfferScene:
https://gist.github.com/macanhajc/0ac98bbd2974d2f6fac96d9e30fd0642
UtilityActions:
https://gist.github.com/macanhajc/f10960a8254b7659457f8a09c848c8cf
As mentioned in another answer, componentWillReceiveProps is being phased out, so I would aim for trying to eliminate it where possible. You'll be future-proofing your code and keeping your component logic more declarative and easy to reason about. As someone who has been responsible for (and been frustrated by) lifecycle method abuse like this, here are some things that have helped me.
Remember that when using redux-thunk, along with passing dispatch as the first argument, you can also pass getState as the second. This allows you to access state values in your action logic instead of bringing them into your component's props and adding clutter. Something like:
export const ExampleAction = update =>
(dispatch, getState) => {
const { exampleBool } = getState().ExampleReducer
if (exampleBool) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update
})
}
}
Using async/await in action logic can be a lifesaver when your action depends upon fetched results from an API call:
export const ExampleAction = () =>
async (dispatch, getState) => {
const { valueToCheck } = getState().ExampleReducer
, result = await someAPICall(valueToCheck)
.catch(e => console.log(e))
if (result.length > 0) {
dispatch({
type: 'UPDATE_EXAMPLE_STATE',
update: result
})
}
}
For cases where your component's rendering behavior depends upon certain state values after your state has been updated, I highly recommend reselect. A very basic example would be something like:
component.js
import React, { Component, Fragment } from 'react'
import { connect } from 'react-redux'
import { shouldDisplayItems } from '../selectors'
import MyListviewComponent from './myListview'
class ItemList extends Component {
render() {
const { shouldDisplayItems, items } = this.props
return (
<>
{shouldDisplayItems && <MyListviewComponent items={items} />}
</>
)
}
}
const mapStateToProps = ({ ListItems }) => shouldDisplayItems(ListItems)
export default connect(mapStateToProps)(ItemList)
selectors.js:
(Assuming your ListItems reducer has the params items and visibilityFilter)
import { createSelector } from 'reselect'
export const shouldDisplayItems = createSelector(
[state => state],
({ items, visibilityFilter }) => {
return {
shouldDisplayItems: visibilityFilter && items.length > 0,
items
}
}
)
I should mention that another option would be using higher-order components, but it can be tricky to use this approach before having a good grasp on how to keep too much imperative logic out of your components (I learned this the hard way).
I agree with #AnuragChutani and #Goldy in terms of clarity of the code; break it down some more into more components or functions.
Now after some review of your componentWillReceiveProps function, it is definitely not specific enough to narrow down exactly which prop changes. If any connected redux variable changes, the componentWillReceiveProps function will be invoked each time.
So e.g. if 'token' or 'selected_product' updates, componentWillReceiveProps will be triggered, even though you did not want it to trigger for token updates.
You can use a comparison for a specific variable update in the props.
E.g Using lodash
if(!_.isEqual( nextProps.selected_product, this.props.selected_product ))
// if props are different/updated, do something
Secondly, you can call actions/callbacks in your actions to narrow down navigation.
E.g.
takePicture = (camera, options){
...
//on success
dispatch(handleModalConfirmPrice())
...
}}

How to work around the require(“../../../../../../../”) frustration In NodeJS?

Any better ways of solving this kind of problem in node.js below?
import foo from "../../../modules/home/models/index.js"
import bar from "../../../modules/about/models/index.js"
import baz from "../../../modules/contact/models/index.js"
At least making them into something like this?
import foo from "/home/models/index.js"
import bar from "/about/models/index.js"
import baz from "/contact/models/index.js"
Any ideas?
You need inversion of control.
./modules/home/index.js
const homeModel1 = () => {
//...
}
const homeModel2 = () => {
//...
}
module.exports = Object.assign({}, { homeModel1, homeModel2 })
1. An object will be exported of the following shape:
{
homeModel1: () => {},
homeModel2: () => {}
}
2. When you add a new model, simply add it or import it into this file and then add it to the export object.
./modules/index.js
import { homeModels } from './modules/home'
import { aboutModels } from './modules/about'
import { contactModels } from './modules/contact'
module.exports = Object.assign({}, { homeModels, aboutModels, contactModels })
The models are destructured out and then exported as methods on a new object.
Likewise, same shape object is exported with all your models cultivated together, bringing all their dependencies with them.
somewhere else
import modules from './modules'
const query = modules.homeModels.homeModel1()
Bonus:
To clarify, Object.assign({}, obj1, obj2) creates a new object with the prototype set to the Object prototype, and merges the properties and methods of obj1 and obj2. In this simple form, it is essentially the same as const obj = {}.
A bit more advanced, is Object.assign({}, { obj1, obj2 }) which makes obj1 and obj2 properties on the new object. You can do some simple testing to get a feel for the data structures.
We also used some destructuring. If you are having issues getting things lined up properly, you should look at those aspects plus how you are importing them into a file. For example, import obj1 from './modules' will bring the entire object in from ./modules, but import { obj1 } from './modules' will destructure obj1 from the object that it pulls in, so obj1 was a method/property of the object.
Do some research into inversion of control and dependency injection.

GitHub Electron: build menu in required file

I am seasoned in JavaScript, but very new to node and to Electron. I am trying to piece the technique together from code samples and what documentation I can find.
I would like to include my menu code in a separate file. The main code is in a file called renderer.js and the menu code in one called menu.js. A simple example:
// renderer.js
function doit() {
alert('hello');
}
module.exports.doit=doit; // Added
var q=require('./menu');
var q=require('./menu');
// menu.js
var template = [
{
label: 'Test',
submenu: [
{
label: 'Something',
click() {
doit();
}
}
]
}
];
const {remote} = require('electron');
const renderer=require('./renderer'); // Added
const {Menu, MenuItem} = remote;
const app=remote.app; // Addes
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
The menu is created, but when selecting the menu item, I get the message: Uncaught ReferenceError: doit is not defined.
I understand the meaning of the message, and clearly variables are not passed between the files.
How can I accomplish this?
Update: I have added some lines in the sample incorporate the accepted answer below. This now works.
Clearly I did not understand the meaning of require(). It strikes me as odd that each file can require the other. Anyway …
Thanks
If you wish to access symbols defined in one Node module from another you have to export them via module.exports:
// renderer.js
function doit() {
// ...
}
module.exports.doit = doit;
And load the module via require:
// menu.js
const { doit } = require('./renderer');
// OR: const doit = require('./renderer').doit;
var template = [
{
label: 'Test',
submenu: [
{
label: 'Something',
click() {
doit();
}
}
]
}
];
This and much more is covered in the Node API docs.
I am trying to solve the same challenge. Currently I am looking into this:
https://github.com/ragingwind/electron-menu-loader
He basically adds a property 'event' and replaces that with an event handler.

YUI, instantiable module that is not a widget?

If I want a module that is instantiable, let say, a module that handles storing preferences in a subcookies, and i want the main cookie to be configurable, but i don't want it to be a widget... what patterns should i use with YUI?
the end code should be something:
Y.use('my-pref-manager', function(Y){
var A = Y.my-pref-manager.prefStore('A"),
B = Y.my-pref-manager.prefStore('B");
// A and B are now loaded with the contents of cookies A and B, if they exist
A.set('xy', 123 );
});
So far i either found patterns that create widgets within my-module or i have to use methods directly in my-method which will be globals and lack initializers, etc.
There is a bunch of ways of doing this. You could do it using Y.Base.create, like below. The code might not be production ready, or even working properly, but hopefully it answers how you can create a module without it being a Widget.
The code below creates a module that extends Y.Base. This let us use Attributes and other cool things. Check the doc for Y.Base.
YUI.add('my-pref-manager', function (Y) {
var PrefManager = Y.Base.create('myPrefManager', Y.Base, [], {
initializer: function () {
this.after('prefsChange', this.changePref);
},
changePref: function (e) {
Y.Cookie.setSub(this.get('prefStore'), e.subAttrName, this.get(e.subAttrName));
},
setPref: function (name, val) {
this.set('prefs.'+name, val);
},
getPref: function (name) {
return this.get('prefs.'+name);
}
}, {
ATTRS: {
prefStore: {
value: null,
setter: function (val) {
return Y.Cookie.set(val, val);
}
},
prefs: {
value: {}
}
}
});
Y.namespace('My').PrefManager = PrefManager;
}, '0.0.1', {
requires: ['base', 'cookie']
});
YUI().use('my-pref-manager', function (Y) {
var A = new Y.My.PrefManager({prefStore: 'userPrefs'}),
B = new Y.My.PrefManager({prefStore: 'displayPrefs'});
A.setPref('x', 3);
A.setPref('y', 54);
B.setPref('tty', 7);
console.log(A.getPref('x')); // 3
});
Try it out: http://jsfiddle.net/B62nu/

Resources