es6 call class methods within class but also within a on click function [duplicate] - ecmascript-6

This question already has answers here:
How to access the correct `this` inside a callback
(13 answers)
Closed 5 years ago.
I have this es6 class:
class CommentsController {
constructor() {
this.$addCommentForm = $('.add-comment')
this.$addCommentButton = $('.add-comment input[type=submit]')
}
init() {
this.addCommentFormListener();
}
addCommentFormListener() {
this.$addCommentButton.on('click', function(e) {
e.preventDefault();
let imageId = parseInt($(this).parents('ul').data('id'));
let inputText = $(this).parents('ul').find('.user-text').val();
let comment = new Comment(inputText, imageId);
debugger;
CommentsController.renderComment(comment, imageId)
});
}
renderComment(comment, imageId) {
let image = Image.all[imageId]
image.comments.push(comment)
$('#images').find(`ul[data-id=${imageId}] ul#comments-${imageId}`).append(`<li>${comment.text}</li>\n`);
}
}
The problem is that at the debugger, I want to call the renderComment function but I cannot because this does not refer to the controller anymore. What can I do?

Use an arrow function instead of a function:
An arrow function does not have its own this; the this value of the
enclosing execution context is used.
However, now you can get the clicked element from this, because this refers to the instance. Instead get the clicked element using Event.target:
addCommentFormListener() {
this.$addCommentButton.on('click', (e) => {
e.preventDefault();
const $el = $(e.target);
const imageId = parseInt($el.parents('ul').data('id'));
constinputText = $el.parents('ul').find('.user-text').val();
const comment = new Comment(inputText, imageId);
this.renderComment(comment, imageId)
});
}

Related

How to call method in symbol without assigning to variable

The following works fine by assigning Symbol to sayHello.
var sayHello = Symbol('method');
const bar = {
[sayHello] () {
console.log('hello')
}
};
bar[sayHello]();
How to trigger the method inside Symbol if as follow
const bar3 = {
[Symbol('method')] () {
console.log('hello')
}
};
const sym = Object.getOwnPropertySymbols(bar3)[0];
bar3[sym]();
See Object.getOwnPropertySymbols documentation.

Function inside a Function not calling in React Native

I am new to react-native and calling a function inside a fucntion.
I have done as below so far :
Step 1 : Created a function _snapshotToArray to convert the firebase snapshot to Arrray.
_snapshotToArray(snapshot) {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
Step 2 : Created another function as below and calling _snapshotToArray inside it.
_readUserDataFromFirebaseConsole() {//once and on
firebase.database().ref('Users/').on('value', function (snapshot) {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}
Talking about this call :
console.log(this._snapshotToArray(snapshot));
When I press CTRL+CLick, it not letting me to navigate to body of the fuction _snapshotToArray.
In Device am getting below error :
_snapshotToArray is not defined
What might be the issue ?
I'm not at my PC right now, so I cannot test it, but from looking at your code, you need to use a different function notation to allow the varibale access of/from parent methods and parent class.
_snapshotToArray = snapshot => {
var returnArr = [];
snapshot.forEach(function(childSnapshot) {
var item = childSnapshot.val();
item.key = childSnapshot.key;
returnArr.push(item);
});
return returnArr;
}
and
_readUserDataFromFirebaseConsole = () => {
firebase.database().ref('Users/').on('value', snapshot => {
console.log(this._snapshotToArray(snapshot));
Toast.show(this._snapshotToArray(snapshot),Toast.LONG);
});
}

Can not stub private element in WCT

Using Polymer 1 and Web component tester... testing in shady dom on chrome.
In WCT, trying to stub spToast.display() with stub('sp-toast', { display: ()=> {} }); but I get error with Attempted to wrap undefined property display as function.... what I am doing wrong?
The reason why I am trying to stub it is because I get spToast.display is not a function when the test runs the code base.
original code:
showAgeWarning: function() {
var spApp = Polymer.dom(document).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
var msg = "foo"
spToast.display('information', msg);
},
test code:
<test-fixture id="sp-veteran">
<template>
<h2>edit veteran</h2>
<sp-app>
<sp-toast></sp-toast>
<sp-veteran>
</sp-veteran>
</sp-app>
</template>
</test-fixture>
setup(function() {
replace('sp-app').with('fake-sp-app');
replace('sp-ajax').with('fake-sp-ajax');
stub('sp-value-dropdown', { setInvalidState: (state)=> {} });
myEl = fixture('sp-veteran');
});
test('it should validate the veteran', function() {
var spApp = Polymer.dom(myEl.root).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
sinon.stub(spToast, 'display');
When you get Attempted to wrap undefined property display as function it means that it can't replace a method that doesn't exist (yet).
If you actually get a value for var spToast = Polymer.dom(spApp.root).querySelector('sp-toast') in your test, and nothing about your test is going to give display a value, you could just set it, a la spToast.display = function() {}; then you should be able to set a spy on it or what have you as needed.
Put it all together and you could have
test('it should validate the veteran', function() {
var spApp = Polymer.dom(myEl.root).querySelector('sp-app');
var spToast = Polymer.dom(spApp.root).querySelector('sp-toast');
spToast.display = function() {};
sinon.spy(spToast, 'display');
// Trigger the side effect that would lead to `display` being called
assert.equal(
spToast.display.calledOnces,
true
);
});

Google Maps not working on tab Ionic

I create tab on Ionic project. When i would access to Google map from another url Tab, it's not working but when i access it directly it works.
First the Ionic part:
The tab showing the map is:
Ionic calls refreshMap() when the user selects the tab.
refreshMap() is:
.controller('MainCtrl', function($scope) {
$scope.refreshMap = function() {
setTimeout(function () {
$scope.refreshMap_();
}, 1); //Need to execute it this way because the DOM may not be ready yet
};
$scope.refreshMap_ = function() {
var div = document.getElementById("map_canvas");
reattachMap(map,div);
};
})
I've implemented reattachMap() looking at the Map.init() method:
function reattachMap(map,div) {
if (!isDom(div)) {
console.log("div is not dom");
return map;
} else {
map.set("div", div);
while(div.parentNode) {
div.style.backgroundColor = 'rgba(0,0,0,0)';
div = div.parentNode;
}
return map;
}
}
function isDom(element) {
return !!element &&
typeof element === "object" &&
"getBoundingClientRect" in element;
}
And that's about it, now when the user switches back to the map tab, it will be there.
Please refer this.
(https://github.com/mapsplugin/cordova-plugin-googlemaps/issues/256/#issuecomment-59784091)

prototype - Trigger event when an element is removed from the DOM

I'm trying to figure out how to execute some js code when an element is removed from the page:
Something in prototype like:
$('custom-div').observe('remove', function(event) {
// Handle the event
});
Does anything like this exist?
In modern browsers, you can use a MutationObserver. Here's code that will call a callback when a DOM element is removed from it's current location:
function watchRemove(el, fn) {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
var item;
if (mutation.type === "childList" && mutation.removedNodes) {
for (var i = 0; i < mutation.removedNodes.length; i++) {
item = mutation.removedNodes[i];
if (item === el) {
// clear the observer
observer.disconnect();
fn.call(item, item);
break;
}
}
}
});
});
observer.observe(el.parentNode, {childList: true});
return observer;
}
And, a working demo: http://jsfiddle.net/jfriend00/naft3qeb/
This watches the parent for changes to its direct children and calls the callback if the specific DOM element passed in is removed.
The observer will remove itself when the DOM element is removed or watchRemove() returns the observer instance which you can call .disconnect() on at any time to stop the watching.
Here's a jQuery plug-in that uses this functionality:
jQuery.fn.watchRemove = function(fn, observers) {
return this.each(function() {
var o = watchRemove(this, fn);
if (observers) {
observers.push(o);
}
});
}
In this case, it accepts an optional array object as an argument that will be filled with all the observer objects (only necessary to pass this if you want to be able to stop the watching yourself on any given item).