How to make a nested function call within an IIFE? - javascript

const parkReport = () => {
return {
averageAge: () => {
return console.log('Something');
}
}
};
const initialize = ( parkReport => {
return parkReport.averageAge();
})(parkReport);
In the IIFE initialize parkReport.averageAge() is showing an error of not a function. How do you call the nested AverageAge() from initialize?

You need to call the parkReport function. Here you are passing parkReport as a callback to the IIFE. so you need to call it to expect something returned from it.
const parkReport = () => {
return {
averageAge: () => {
return console.log('Something');
}
}
};
const initialize = (parkReport => {
return parkReport() // call it
.averageAge(); // and get the age
})(parkReport);

Related

Why useState variable gets undefined inside try catch statement in an asynchrone function?

I create a hook that manages the state of a single object with fetch to api. This hook exposes function to interact with this object.
// the hook
const useMyHook = () => {
const [myObject, setMyObject] = useState(null);
useEffect(() => {
const fetchData = async () => {
const data = await fetchSomething();
setMyObject(data);
}
fetchData();
}, []);
const updateMyObject = async () => {
console.log(myObject); // log : { ... }
try {
console.log(myObject); // log : undefined
// ...
} catch(err) {
// ...
}
};
return {
updateMyObject,
myObject
};
};
Then i use this hook inside a component and trigger updateMyObject() with a button.
// the component
const MyComponent = () => {
const { myObject, updateMyObject } = useMyHook();
return (
<button onClick={updateMyObject}>
Click me
</button>
);
};
How is this possible that before the try catch block the log is clean and inside the block i get undefined ?
I think this gonna work
useEffect(() => {
const fetchData = async () => {
const data = await fetchSomething();
setMyObject(data);
}
If(!myObject)
fetchData();
}, [myObject]);
Your code is perfectly alright !! There could be a problem in the fetchSomething() method. Ideally, it should return data, but it's not doing the same job.
Here is a small example. You can give it a try.
const fetchSomething = async () => {
const response = await fetch(
"https://jsonplaceholder.typicode.com/posts/1"
).then((res) => res.json());
return response;
};

Is it possible to pass an argument to a variable initialized using let?

Below is the code snippet used in one of the tutorials I am learning from now. Can someone please help to understand how an argument 'mediastate' can be passed to a variable 'transientListen' in the 'notify' function?
function createMediaListener(queries) {
let transientListener = null;
const keys = Object.keys(queries);
const queryLists = keys.reduce((queryLists, key) => {
queryLists[key] = window.matchMedia(queries[key]);
return queryLists;
}, {});
const mediaState = keys.reduce((state, key) => {
state[key] = queryLists[key].matches;
return state;
}, {});
const notify = () => {
if (transientListener != null) transientListener(mediaState);
};
const listeners = keys.reduce((listeners, key) => {
listeners[key] = event => {
mediaState[key] = event.matches;
notify();
};
return listeners;
}, {});
const listen = listener => {
transientListener = listener;
keys.forEach(key => {
queryLists[key].addListener(listeners[key]);
});
};
const dispose = () => {
transientListener = null;
keys.forEach(key => {
queryLists[key].removeListener(listeners[key]);
});
};
const getState = () => mediaState;
return { listen, dispose, getState };
}
export default createMediaListener;
How I understand, the "listen" function is called by return statement in the module. The problem is, "listen" function needs a parameter, otherwise is: transientListener = listener; => undefined.

Modify wrapper function for a function with parameter

I have a wrapper function as
const wrap = (func) =>{
return () => {
try {
return func();
} catch (e) {
console.log(e.message);
return null;
}
};
}
how should i modify my wrapper function(wrap) to handle both the function call i.e one with param and other without param
Simply pass args to your wrapped function and accept them in the wrapper one:
const wrap = (func) =>{
return (...args) => {
try {
return func(...args);
} catch (e) {
console.log(e.message);
return null;
}
};
}
PS: Peach is not gross.

Testing nested function in Jest

I have in file.js code which I simplify this way:
function Apple(,data) {
this.attr1 = data.attr1,
this.attr2 = data.attr2,
this.doSomething(data.flag);
}
Apple.prototype = new function() {
this.function1 = function() {
// do something
}
this.doSomething = function(flag) {
// return value
}
}
I want to test function1(), for that, I want to mock first doSomething() to return a specific value, but I am failing because any call to Apple() function executes immediately doSomething():
describe('Apple', () => {
test('test function1()', () => {
Apple.doSomething = jest.fn().mockImplementation((2) => {
// do something;
});
let apple = new Apple(data); // the original doSomething() executes here instead of the mocked version
});
});
How can I achieve my goal ?
Try using spyOn:
const mockDoSomething = jest.spyOn(Apple.prototype, 'doSomething').mockReturnValueOnce((flag) => {
// mock do something;
})

Is this a valid recursive function?

I found a recursive expression in a library very confused.
The code is here :
https://github.com/tappleby/redux-batched-subscribe/blob/master/src/index.js#L22
export function batchedSubscribe(batch) {
if (typeof batch !== 'function') {
throw new Error('Expected batch to be a function.');
}
const listeners = [];
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
const index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
}
function notifyListenersBatched() {
batch(() => listeners.slice().forEach(listener => listener()));
}
return next => (...args) => {
const store = next(...args);
const subscribeImmediate = store.subscribe;
function dispatch(...dispatchArgs) {
const res = store.dispatch(...dispatchArgs);
notifyListenersBatched();
return res;
}
return {
...store,
dispatch,
subscribe,
subscribeImmediate
};
};
}
Specifically this part:
return next => (...args) => {
const store = next(...args);
const subscribeImmediate = store.subscribe;
function dispatch(...dispatchArgs) {
const res = store.dispatch(...dispatchArgs);
notifyListenersBatched();
return res;
}
return {
...store,
dispatch,
subscribe,
subscribeImmediate
};
};
How is this not infinite recursion?
How is this not infinite recursion?
There is absolutely no recursion here. The syntax next => (...args) => … does not translate to
return function next(...args) {
const store = next(...args);
…
but rather to
return function(next) {
return function(...args) {
const store = next(...args);
…
So unless the caller of that function does something weird like var f = batchedSubscribe(…); f(f)(f)…;, it won't call itself.
The reason we both seemed confused by this is because the arrow function, if written as a single statement, implicitly calls return.
So for example a simple function like this:
const add = (a, b) => a + b;
is equivalent to
var add = function(a, b) {
return a + b;
}
Knowing this we can remove the sugar and convert the arrow functions:
return next => function(...args) { // body }
Is really what's going on here, and if we go one step further we get this:
return function(next) {
return function(...args) {
const store = next(...args);
const subscribeImmediate = store.subscribe;
function dispatch(...dispatchArgs) {
const res = store.dispatch(...dispatchArgs);
notifyListenersBatched();
return res;
}
return {
...store,
dispatch,
subscribe,
subscribeImmediate
};
}
}
Both functions that are containing the code are actually nameless. next is a function, but not one of the functions being returned. It is passed as a variable into the first returned function.
There's no recursion here, but rather a lot of function composition, which is to be expected from a library like redux that draws so much from functional programming.

Categories

Resources