0

I can't for the love of god find anything on this, or I just don't know exactly what to search for. I'm new to React and React Native and I need help with my RN project. What I'm trying to do is call a function auto_login() in my component MainLogic. The function looks as follows and is placed in the module.exports:

auto_login: function(navigator){
    if(GLOBALS.LOGGED_IN != true){
      Keychain
      .getGenericPassword()
      .then(function(credentials){
        fetch(GLOBALS.API_URL, {
          method: "POST",
          headers: {
            'Accept': 'application/x-www-form-urlencoded',
            'Content-Type': 'application/x-www-form-urlencoded',
          },
          body: "username=" + credentials.username + "&password=" + credentials.password,
        })
        .then((response) => response.json())
        .then((response) => {
          if(JSON.stringify(response.status).replace(new RegExp('"', 'g'), '').match("OK")){
            GLOBALS.LOGGED_IN = true;
            GLOBALS.USERNAME = credentials.username;
            GLOBALS.PASSWORD = credentials.password;

            navigator.push({
              id: 'news'
            });
          }
        })
        .catch((e) => {
          console.warn(e);
        })
        .done();
      });
    }
  },

Right now I'm calling this function from

componentDidMount: function(){
  MainLogic.auto_login(navigator);
},

before the render function but I realise the navigator is out of context or something. I'd like some help to understand how I'd go about calling this function and binding the navigator properly. I'm right now getting a warning:

TypeError: navigator.push is not a function. (in 'navigator.push({id:'news'})', 'navigator.push' is undefined.

Any help in understanding this is highly appreciated!

Edit: I'm using React.createClass.

Johannes Nyman
  • 319
  • 2
  • 4
  • 16
  • Try adding a constructor with a line below super(); this.auto_login = this.auto_login.bind(this); – eden Jan 03 '17 at 10:56
  • To clarify: I'm using the React.createClass, not ES6. Do you know anything similar that can be applied to my structure? – Johannes Nyman Jan 03 '17 at 12:30
  • componentWillMount: function() { this.auto_login = this.auto_login.bind(this); } – eden Jan 03 '17 at 12:31
  • @EnieJakiro Ah, I see. So I tried this, but instead used "this.auto_login = MainLogic.auto_login.bind(this);" since the function is in the MainLogic component and not in the index file. But I get the warning "undefined is not an object (evaluating '_this.refs')". The line throwing the error in auto_login() is "this.refs["nav"].push({id: 'news'});". Any ideas? – Johannes Nyman Jan 03 '17 at 12:43
  • I think problem is that your this keyword is out of the scope. Since refs should always be defined. Are you certain of that binding? Can you try 'this.auto_login = this.auto_login.bind(this);' maybe MainLogic refer to something I'm not aware of. – eden Jan 03 '17 at 12:47
  • I would also suggest ES6 feature arrow functions, which binds your function but you aren't using ES6. – eden Jan 03 '17 at 12:48
  • http://stackoverflow.com/questions/15455009/javascript-call-apply-vs-bind check this link, it may help at binding and calling your function in sequence, in your componentDidMount(). – eden Jan 03 '17 at 12:56
  • @EnieJakiro Wow, thanks for all the great help! Though I gotta admit I'm still a bit lost when it comes to applying the solutions from that link. To clarify what MainLogic is: "import MainLogic from './app/components/logic/main_logic.js';" (at the top of index.ios.js). I've tried "this.auto_login = this.auto_login.bind(this)" after placing the auto_login() function in index.ios.js, I still end up with the same warning. From my understanding it seems like you said that "this" is out of the scope. Is refs supposed to be defined even in componentDidMount()? – Johannes Nyman Jan 03 '17 at 13:22
  • I've also tried "this.auto_login.apply(this);" and "this.auto_login.call(this);" in componentDidMount(); with no success – Johannes Nyman Jan 03 '17 at 13:24
  • Shall we move to chat? I think I can help you if you send me the files. – eden Jan 03 '17 at 13:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/132196/discussion-between-enie-jakiro-and-johannes-nyman). – eden Jan 03 '17 at 13:25

1 Answers1

1

Since you're trying to replace your navigator in main_logic.js file, this keyword in auto_login didn't point your function's context. Binding also didn't help since this keyword remained pointing the same context.

Best way I can think of is passing the context, this keyword, to main_logic.js and then instead of calling

this.refs['nav']

we'll change it into

paramName.refs['nav']

I suspect there could be better solutions, so I'm encouraging you to take a deeper look and iterate the problem as you advance in React Native and JS.

eden
  • 5,876
  • 2
  • 28
  • 43