how to use the google-translate-api translation outside the method? - javascript

I started using Cloud Google and implemented the translation API in my code but I can't use the response outside the callback.
methods:{
clicked(){
const text = "Olá";
const target = navigator.language;
googleTranslate.translate(text, target, function(err, translation){
console.log(translation.translatedText)
//this.newText = translation.translatedText;
});
//console.log(this.newText);
},
}
Show the error with or without the console.log. In the this.newText = translation.translatedText;
Error in render: "TypeError: Cannot read property 'newText' of undefined"
I would like to show the user the answer in the template. How can I do it?

Using the function keyword changes the 'this' context. You can either save 'this' outside of the function or use arrow functions.
Here's how you would use an arrow function
methods:{
clicked(){
const text = "Olá";
const target = navigator.language;
googleTranslate.translate(text, target, (err, translation) => {
console.log(translation.translatedText)
//this.newText = translation.translatedText;
});
//console.log(this.newText);
},
}

Related

Why am I unable to access class properties inside of a passed function of an Angular component?

I am using HTML 5 geolocation inside an Angular component:
...
export class AngularComponent {
...
constructor(private db: DatabaseService) {}
// this function is assigned to an HTML button
logCoords(message, action) {
navigator.geolocation.getCurrentPosition(this.success, this.error, this.options);
}
success(pos) {
function time() {
...
}
var crd = pos.coords;
var lat = crd.latitude
var long = crd.longitude
let newCoordinates = {'lat': lat, 'long':long, 'time': time}
this.db.addLocation(newCoordinates)
}
...
}
...
I want to store the result of the getCurrentPosition Method inside indexed db using an Angular service but I am unable to access any properties of the component class (this.db is null).
Why I am unable to access this.db inside the success function and how I might be able to work around this?
Issue is with the below line:
navigator.geolocation.getCurrentPosition(this.success, this.error, this.options);
In above line, you are just passing this.success as callback without setting context to it. So in this case as per javascript principles, this would always refer to window object while you are expecting component reference.
To fix this, you have to set the context (component instance) before passing this.success and for that purpose javascript provided bind() function.
Try below code (very simple fix) -
navigator.geolocation.getCurrentPosition(this.success.bind(this), this.error.bind(this), this.options);
For more details around bind() function refer below link -
https://developer.mozilla.org/enUS/docs/Web/JavaScript/Reference/Global_objects/Function/bind
Because you lose the context this when passing the method as a callback.
You can fix this by multiple ways:
logCoords(message, action) {
// bind context
navigator.geolocation.getCurrentPosition(this.success.bind(this), this.error.bind(this), this.options);
}
or
logCoords(message, action) {
navigator.geolocation.getCurrentPosition(this.success, this.error, this.options);
success = (pos) => {} // <= arrow function
error = () => {} // <= arrow function
}

How to access 'this' keyword inside of static method in react native?

I am not able to access 'this' keyword in my static method in react- native, when I try to access it, it's thrown me error like 'this.setState not a function'.
Here is my code.
static getShiftStatus = () =>{
//for check shift start or not
Usermodal.getShiftStatus((isStatus) =>{
this.setState({isShiftStart: isStatus}) //error occure here.
console.log(a.state.isShiftStart)
})
}
this in the inner function points to something else.
You need to capture the this from the outside function.
static getShiftStatus = () =>{
var that = this; // capture here
Usermodal.getShiftStatus((isStatus) =>{
that.setState({isShiftStart: isStatus}) // use it here
console.log(a.state.isShiftStart)
})
}

Avoid using extra variable for storing reference in es6

I'm already using react es6 but still in this case, I don't know how to avoid using that for this:
const that = this;
UploadApi.exec(file).then(data => {
that.setState({ loading : false});
});
In this example, you are already using arrow function, so storing the reference in a separate variable is not required. You can directly use this keyword like this:
//const that = this;
UploadApi.exec(file).then(data => {
this.setState({ loading : false});
});
Storing the reference in a separate variable required, when you use callback method like this:
const that = this;
UploadApi.exec(file).then(function(data){
that.setState({ loading : false});
});
But, you can avoid the extra variable by using .bind(this) with callback method, like this:
//const that = this;
UploadApi.exec(file).then(function(data){
this.setState({ loading : false});
}.bind(this));
Check this answer for complete detail, arrow function vs function declaration
You need to create yout UploadApi.exec that way so that after transpiling your javascript get created accordingly..like below
In you UploadApi
exec=(file:any):Q.Promise=>{
}
and then use it like below
UploadApi.exec(file).then(data => {
this.setState({ loading : false});
});

Javascript/Typescript 'this' scope

I am working with Ionic2 and Meteor. I do however have a Javascript/Typescript issue relating to the scope of the this object.
I have read that I should use bind when I don't have handle on this at the appropriate level.
I probably don't understand the concept, because I try the following, but get an error trying to call a function.
this.subscribe('messages', this.activeChat._id, this.senderId, () => {
this.autorun(() => {
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach(function (message: Message) {
setLocalMessage.bind(message);
});
});
});
and
private setLocalMessage(message: Message): void {
this.localMessageCollection.insert(message);
}
I get the following error when I try build the app:
ERROR in ./app/pages/messages/messages.ts
(72,19): error TS2304: Cannot find name 'setLocalMessage'.
UPDATE
Thank you for the advise below.
I am now using the following, and it works.
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach((message: Message) => {
this.setLocalMessage(message);
});
});
I have read that I should use bind when I don't have handle on this at the appropriate level.
That's a bit outdated now, better have a look at How to access the correct `this` context inside a callback? these days which also shows you how to use arrow functions.
You're getting the error message because setLocalMessage is not a variable but still a property of this so you have to access it as such. There are basically three solutions in your case:
bind
messageData.find().forEach(this.setLocalMessage.bind(this));
the context argument of forEach (assuming it's the Array method):
messageData.find().forEach(this.setLocalMessage, this);
another arrow function:
messageData.find().forEach((message: Message) => {
this.setLocalMessage(message);
});
There are a few things wrong here.
In ES6 (and thus TypeScript), you need to refer to instance members using explicit this, such as this.setLocalMessage. Just writing setLocalMessage is invalid no matter where the code is.
Inside a function, the this object will probably not be what you expect anyway. You need to capture the this object from outside the function and put it in a variable, like so:
this.subscribe('messages', this.activeChat._id, this.senderId, () => {
this.autorun(() => {
let self = this;
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach(function (message: Message) {
self.setLocalMessage(message);
});
});
});
Alternatively, you can use an arrow expression, in which this is the same as what it is in the code around it:
this.subscribe('messages', this.activeChat._id, this.senderId, () => {
this.autorun(() => {
let promiseMessages: Promise<Mongo.Collection<Message>> = this.findMessages();
promiseMessages.then((messageData: Mongo.Collection<Message>) => {
messageData.find().forEach(message => this.setLocalMessage(message));
});
});
});
It's not an issue of TypeScript itself. Without it, the code will just fail at runtime.

Socket.io + node : TypeError: Object #<Namespace> has no method

I have a simple JavaScript class like that :
function MySIOClass(io)
{
this.io = io
this.ns = this.io.of('/notif')
this.init()
}
MySIOClass.prototype.init = function (){
this.ns.on('connection', this.newClient)
}
MySIOClass.prototype.newClient = function (socket)
{
socket.on('msg', function (data){ this.handle_msg(data)})
 }
MySIOClass.prototype.handle_msg = function (data)
{
// handle my message
}
I get stuck on the function newClient, each time a socket.io client send an event 'msg', the console triggers
TypeError: Object #<Socket> has no method 'handle_msg'
I tried to keep a reference of the operator this inside the function newClient like that :
MySIOClass.prototype.newClient = function (socket)
{
var c = this;
socket.on('msg', function (data){ c.handle_msg(data)})
 }
But no luck too, i got the following error about namespace :
TypeError: Object #<Namespace> has no method 'handle_msg'
My class is exported via a module, everything works except when i try to add a listener with the on method of socket.io inside a class. I have correctly used the "new" operator when i instantiated my class.
Could you help me figure out what's happening ? i tried several things, but none of them worked.
Thanks for your time.
When you pass this.newClient to .on('connection', ...), you are passing just the function itself and losing the (this) context. You need to either create a wrapper function that can access the correct context to call newClient() properly or create a bound version of newClient.
First option:
MySIOClass.prototype.init = function (){
var self = this;
this.ns.on('connection', function(socket) {
self.newClient(socket);
});
}
Second option:
MySIOClass.prototype.init = function (){
this.ns.on('connection', this.newClient.bind(this));
}
Regarding the error inside newClient() itself, you are correct in that you have to use a "self"/"that" variable that you can use to access the correct context to call handle_msg().

Categories

Resources