React - super and functions overriding parents - javascript

I've got a little problem occurring with super and functions overriding the parent ones.
A simplified example of my problem is the following, having 2 files:
FileA.js
constructor () {
...
}
myFunction = () => {
...
}
FileB.js
class FileB extends FileA {
constructor () {
...
}
myFunction = () => {
if () {
// do something
} else {
super.myFunction()
}
}
render () {
return <button onClick={() => this.myFunction()}
}
}
First of all, if the else condition is invoked from FileB.js, an error is launched:
TypeError: (intermediate value).myFunction is not a function
But if I make the myFunction of FileB.js a non-arrow function, this one is never fired, and instead is fired the one from FileA.js.
Why is this happening and how to solve it?

Related

How to call another function inside function in export default?

export default {
one: () => {
//some codes
},
two: () => {
//some codes
one(); // error
this.one(); // error
}
}
I have module like that, and I want to call function one() inside function two().
But I got error like this : TypeError: Cannot read property 'one' of undefined.
How can I fix it? I want to know the cause.
What about extracting them out into separate functions and then include them in the export?
const one = () => {
//some codes
};
const two = () => {
//some codes
one();
};
export default {
one,
two
}
You shouldn´t use arrows function if you want to give a new context to the this keyword.
Look this example, it uses an arrow function in the two method. It would return error since the this keyword is not related to the object, but mantains the context from the last function.
let obj = {
one: function() {
console.log("one");
},
two: () => { // Arrow function
this.one();
}
}
obj.two();
If you use a normal function, the this keyword would be related to the object:
let obj = {
one: function() {
console.log("one");
},
two: function() { // Normal function
this.one();
}
}
obj.two();
This is the main difference between arrow functions and normal functions

How to properly call an init function in a ts class

I'm writing some tests for a class. In my tests if I don't call browserViewPreload.init() the test fails, but when I do call browserViewPreload.init() it passes.
Why should I need to explicitly call browserViewPreload.init() in the test when I've already done it in my beforeEach block?
//myFile.ts
export default class BrowserViewPreload {
constructor(){
this.init();
}
attachMouse(){
console.log('attaching mouse')
}
init(){
return document.addEventListener('DOMContentLoaded', this.attachMouse)
}
}
//myFile.spec.ts
import BrowserViewPreload from './browserViewPreload'
function bootStrapComponent() {
return new BrowserViewPreload();
};
describe('BrowserViewPreload Class', () => {
var browserViewPreload;
let initSpy
let docspy
let mouseSpy
beforeEach(()=>{
browserViewPreload = bootStrapComponent();
initSpy = jest.spyOn(browserViewPreload, 'init')
docspy = jest.spyOn(document, 'addEventListener')
})
it('should report name', () => {
//browserViewPreload.init(); not including this makes the tests fail. Why do I need to make the call here when I've already done so in the beforeEach
expect(initSpy).toHaveBeenCalled();
expect(docspy).toHaveBeenCalled();
document.dispatchEvent(new Event('DOMContentLoaded'));
expect(mouseSpy).toHaveBeenCalled();
});
});
I guess it's because you are creating BrowserViewPreload object before attaching the initSpy to it.

Calling an array of a different function that belongs to the same javascript class

Hi guys I'm a newbie in JS and I'd like to know how to call an array of a different class inside another function that belongs to the same javascript class.
Here is the sample code:
class Something {
constructor () {}
async functionA () {
this.list = []
}
async functionB () {
console.log(this.list)
}
}
In the constructor you can declare your variables with this.variableName and then other class methods will be able to get and set the value. You can also access it from an instance of the class.
class Something {
constructor() {
this.list = []
}
async functionA () {
this.list = [ 'foo', 'bar']
}
async functionB () {
console.log(this.list)
}
}
What you're doing seems to work fine...
class Something {
constructor () {}
async functionA () {
this.list = ['ok']
}
async functionB () {
console.log(this.list)
}
}
const a = new Something();
a.functionA();
a.functionB();
https://codepen.io/benaloney/pen/dyPpELK

Parent class's function is called instead of sub-class's function while overriding function in javascript es-06

I'm using javascript es-06 syntax in react-native for developing mobile apps. Here is my code:
Super class:
export class ApiCallback {
onResponse = (responseJson) => {
console.log("super response")
}
onError = (error) => {
console.log("super error")
}
}
Base class:
export class LoginCallback extends ApiCallback {
onResponse(responseJson) {
super.onResponse(responseJson)
console.log(responseJson)
}
onError(error) {
super.onError()
console.error(error)
}
}
Usage:
export class AuthenticationInteractor {
doLogIn(loginCallback: LoginCallback) {
fetch("http://google.com",
{
method: "GET"
})
.then((responseJson) => {
loginCallback.onResponse(responseJson)
})
.catch((error) => {
loginCallback.onError(error)
})
}
}
and
new AuthenticationInteractor().doLogIn(new LoginCallback())
Here, instead of calling base class method (which is printing all resonse json in onResponse()), it's calling parent class's onResponse() function and printing
"super response"
as result from base class's onResponse() function.
The simple answer is: you shouldn't use arrow functions as methods in classes.
export class ApiCallback {
onResponse(responseJson) {
console.log("super response")
}
onError(error) {
console.log("super error")
}
}
The complex answer is: when you declare class method as arrow function it won't be added to class prototype but will be added to object on initialization. In your case you add LoginCallback methods to prototype, but on initialization they were overwritten by methods from parent class.
So it's better to use classic functions as class methods always. But don't forget to bind context to them.
Please see below snippet, it will improve the understanding of function definition.
I think the abc = function(){}'s priority is bigger than function abc(){}.
So to replace the function in derived class you have to define the function in same way.
So in your case use
onResponse(responseJson) { console.log("superresponse")}
on parent class will solve the problem.
abc = function(){
console.log("abc");
}
function abc(){
console.log("def");
}
abc();
function def(){
console.log("abc");
}
function def(){
console.log("def");
}
def();
var ghi =function(){
console.log("abc");
}
var ghi = function(){
console.log("def");
}
ghi();

flowtype - How to handle mixins

I have an interface/type defined and I don't want to redefine it everywhere I want to use the mixin. Think facebook's mixins: [] property
Example usecase:
const mixin = root => Object.assign(root, {bar: () => 'baz'));
class Foo {
constructor () { mixin(this); }
test () { console.log(this.bar()) } // <-- this gives an error
}
From what I could find online, this is what i've tried:
interface MyMyxin {
bar () : string;
}
function mixin <T:Object> (root: T) : T & MyMyxin {
return Object.assign(root, {bar: () => 'baz'});
}
class Foo {
constructor () {
mixin(this);
}
test () {
console.log(this.bar()); // <-- no luck
}
}
mixin(Foo.prototype) // <--- this also does not work
But I can't get flow to understand that the mixin method adds an extra property to the object

Categories

Resources