In react, I define a function but it's appear undefine - node.js

I defined a function, but it's undefined in the reference precess. I tried to add breakpoints, the results show that it is a function, but continues to perform an error again, you mean form the callback?
That's the part I quoted, prompt requestServer is not the function, but it has been defined in the code below, the reason why I don't know whether the callback
import React, {Component, PropTypes} from 'react';
import GLogin from './Login';
var serverMethon = require('../../server/requestServer');
export default class LoginContainer extends Component {
constructor(props) {
super(props);
this.state = {
}
}
getLogin = (value) => {
const {selectView} = this.props;
const requestServer = serverMethon.requestServer;
requestServer('login', value, function(t) {
const data = JSON.parse(t.text);
if (data.state != "successful") {
alert("Login fail!")
return;
}
selectView('SearchContainer');
})();
}
render() {
return (
<GLogin
getLogin={this.getLogin}
{...this.props}/>
)
}
}
Function definitions section
var superagent = require('superagent');
export const requestServer = (position, info, callback) => {
superagent.post(`http://localhost:3000/${position}`)
.send(info)
.end((error, doc)=>{
if(error){
throw error
}
callback(doc)
})
}

// proper way
class App extends React.Component{
constructor (props){
super(props);
this.sampleMethod = this.sampleMethod.bind(this);
}
sampleMethod(){
console.log('Sample method called');
}
render(){
return <button onClick={this.sampleMethod}>Click Me</buttom>
}
}
Your mistake is you called your method as this.getLogin. But you don't bind the method. So you can't use this method with this.getLogin. You can use getLogin method without binding. This time you called the method by getLogin but you get context inside getLogin method the context is not be your component. At the time your context is window so you get window object.
So first bind your method then use it.
// your mistake
getLogin = (value)=>{
// your logic
}
// proper way
getLogin(value){
// your logic
}

Related

This in classes and regular functions JS

When we have an object and a method inside it, this refers to the object that it belongs to:
let myObj = {
data: 'someData',
test() {
console.log(this);
},
};
myObj.test();
here the result is : myObj
but what if my method is in a class with constructor?
export default class MovieCard extends React.Component {
constructor(props) {
super(props);
this.state = { content: 'test' };
}
changer() {
console.log(this);
}
render() {
return null;
}
}
It seems, in this case, this equals to 'undefined'
why is that? is it because it has not been called yet?
It is a special case when your class is a React.Component. The this keywords in methods (except the constructor) of such classes is not automatically bound to the instance of the component.
A common solution is to add the following line to the constructor (for each method using this):
constructor(props) {
// ...
this.changer = this.changer.bind(this);
}
It makes sure that your methods have correctly bound this's.
For details of bind(): MDN Web Docs

Adonis: ReferenceError view is not defined

I have controller like this
class TicketController {
index(){
return view.render('tickets')
}
}
and create file in resource\view\tickets.edge and my route is
const Route = use('Route')
Route.resource('tickets', 'TicketController');
when I go to http://127.0.0.1:3333/tickets show me this error
ReferenceError
view is not defined
You need to use view object from http context :
index ({ view }) {
return view.render('hello-world')
}
Adonis documentation example
I had forgotten to import view class and fix it by this code:
const view = use('View');
class TicketController {
index(){
return view.render('tickets')
}
}

How to spy on functions outside a component?

// ./index.js
import { Component } from 'react';
export default class Test extends Component {
method () {
console.log('method()');
}
do () {
this.method();
func();
}
render () {
return null;
}
}
export function func () {
console.log('func()');
}
// ./index.test.js
import { shallow } from 'enzyme';
import React from 'react';
import * as Test from './index';
describe('<Test>', () => {
const component = shallow(<Test.default/>),
method_spy = jest.spyOn(component.instance(), 'method'),
func_spy = jest.spyOn(Test, 'func');
test('func()', () => {
component.instance().do();
expect(method_spy).toHaveBeenCalledTimes(1); // passed
expect(func_spy).toHaveBeenCalledTimes(1); // failed
});
});
I want to spy on function outside a component, but It doesn't work well.
I've got a message like Expected mock function to have been called one time, but it was called zero times.
And I don't want to use mock() method instead of spyOn() in the situation.
Is there way to fix it? Thaks you for reading. :D
It doesn't work because this line:
const func_spy = jest.spyOn(Test, 'func');
...is creating a spy on the module export for func...
...but Test.do doesn't call the module export for func, it calls func directly.
There are two options to fix it.
One is to move func into its own module.
Then the module export for it will be imported into index.js and called within Test.do...
...and when the module export for func is wrapped in a spy the spy will get called by Test.do.
The other option is to note that "ES6 modules support cyclic dependencies automatically" so a module can be imported into itself.
If the module is imported into itself then Test.do can call the module export for func:
import { Component } from 'react';
import * as index from './index'; // <= import the module into itself
export default class Test extends Component {
method() {
console.log('method()');
}
do() {
this.method();
index.func(); // <= use the module
}
render() {
return null;
}
}
export function func() {
console.log('func()');
}
...and the spy on the module export for func will be called as expected:
import { shallow } from 'enzyme';
import React from 'react';
import * as Test from './index';
describe('<Test>', () => {
const component = shallow(<Test.default />),
method_spy = jest.spyOn(component.instance(), 'method'),
func_spy = jest.spyOn(Test, 'func');
test('func()', () => {
component.instance().do();
expect(method_spy).toHaveBeenCalledTimes(1); // Success!
expect(func_spy).toHaveBeenCalledTimes(1); // Success!
});
});

React.JS - Calling a function on `onClick` event causes `this` to be undefined in function

I have the following React.JS (Next.JS) code:
export default class NavBar extends React.Component {
constructor(props) {
super(props);
this.state = {
menuOpen: false
};
}
render() {
return <img id="menu-button" src="/static/menu.svg" onClick={this.toggleMenu}></img>;
}
toggleMenu() {
this.setState({ menuOpen: this.state.menuOpen ? false : true });
}
};
However, when the image is clicked, and toggleMenu is called, I get an error saying that this is undefined. This makes sense, since the function is being put into the onClick event, but how can I fix this?
You need to either explicitly bind this context to your function like:
this.toggleMenu.bind(this)
or re-define your toggleMenu function using arrow notation which does this implicitly:
toggleMenu = () => {
// method body here...
}

How to get GET paramater in Angular2?

By accessing myproject.dev/people?filter%5Bindustry%5D=finance&filter%5BstartWith%5D=a, Angular2 point the url to myproject.dev/people
Here is my RouteConfig:
#RouteConfig([
{
path: '/people',
name: config.route.main,
component: MainComponent,
useAsDefault: true
}
])
In MainComponent:
/// <reference path="../../../typings/angular2.d.ts" />
import {Component, Injector} from 'angular2/core';
import {ROUTER_DIRECTIVES, Router, RouteParams} from 'angular2/router';
import {BaseResourceComponent} from '../../Component/BaseResourceComponent';
import {Status as MainStatus} from '../../reusable/modules/status.svc';
import {Status} from '../../reusable/modules/status.svc';
import {Config} from "./Config";
import URI from 'urijs';
export class MainComponent extends BaseResourceComponent {
constructor(config: Config, status: Status, mainStatus: MainStatus, private router: Router, private routeParams: RouteParams) {
super(config, status, mainStatus);
}
onInit() {
var path = new URI(window.location.href);
path.setQuery('filter[industry]', 'fashion');
path.setQuery('filter[startWith]', 'a');
console.log(path);
console.log(this.router);
//this.router.root.lastNavigationAttempt = "/people?filter%5Bindustry%5D=finance&filter%5BstartWith%5D=a"
console.log(this.routeParams);
// this.routeParams returns {params: Object}
// this.routeParams.params.get('filter') return null
}
}
I still can get it from this.router.root.lastNavigationAttempt, but this is kind of tricky way to get it only. Any better way to get the GET parameters?
In the root component you can inject the router and subscribe, then on route events get the params from the router like
export class AppComponent {
constructor(private router:Router) {
router.subscribe(route => {
console.debug(this.router.currentInstruction.component.params);
});
}
}
On components added by the router you can inject RouteParams directly like
export class Other{
constructor(private routeParams: RouteParams) {
console.debug(this.routeParams);
console.log(this.routeParams.get('filter_industry'));
console.log(this.routeParams.get('filter_start_with'));
}
}
Plunker example
My solution : certainly not the best way t odo it but it work :
I assume that you have this kin of url :
http://localhost:8080/contextPath/index.html?login=true#token_type=Bearer&expires_in=9999&access_token=xxxXXXXXxxx
//get base url to get the token
if
(this.location == "")
{
console.log("traitement location");
this.location = location.href;
}
//extract all :
if (this.location != "") {
console.log("traitement token");
this.login = this.location.split("?")[0].split("=")[1];
this.token_type = this.location.split("?")[1].split("#")[1].split("&")[0].split("=")[1];
this.expire_in = +this.location.split("?")[1].split("#")[1].split("&")[1].split("=")[1];
this.setLocalDateValid((this.expire_in + this.nowDate()).toString());
this.token = this.location.split("?")[1].split("#")[1].split("&")[2].split("=")[1];
}
// then store it
this.setLocalToken(this.token);
Certainly not the best way to do it but it work perfectly well :)
#Günter Zöchbauer is correct. Child route can only use matrix parameter but not query parameter.

Resources