0

I have a MobX store like the following Store class. When I want to access this.user.permits.db, I receive an error that this.user is undefined. I wonder why I cannot access the @observable user.

src/ui/store/store.js file:

import { action, observable } from 'mobx'

import { useStrict } from 'mobx';
useStrict(true);

class Store {
    constructor(){
        //
    }
    @observable user

    @action setUser=(user)=>{
        this.user=user
    }

    @observable menus=[
        {menu1: 'DATABASE',
        /*menu2s: ['PC', 'NETWORK', 'TEL', 'PTT'],*/ //-> this line works fine
        menu2s: this.user.permits.db, //-> this line gives an error: Cannot read property 'permits' of undefined
        }
    ]
}

export default new Store

src/ui/ui.js file which imports store from store.js:

import React from 'react'
import ReactDOM from 'react-dom'

import Layout from './components/layout.js'

import Store from './store/store.js'

//user comes from HTTP GET request
Store.setUser(user)

ReactDOM.render(<Layout store={Store}/>,document.getElementById('ui'))

src/views/profile.ejs file, passing user to JavaScript:

<!DOCTYPE html>
<html lang='en'>

<head>
    <title>User profile</title>
    <link href="/css/style.css" rel="stylesheet" type="text/css">
</head>

<!--
Pass variables from http GET to JavaScript
also block script injection attacks
ref: https://stackoverflow.com/a/16098699/7312233 
-->
<script>
    function htmlDecode(input){
        var e=document.createElement('div');
        e.innerHTML=input;
        return e.childNodes.length===0?"":e.childNodes[0].nodeValue;
    }
    var user=JSON.parse(htmlDecode("<%= JSON.stringify(user) %>"));
</script>

<div id="ui"></div>

<script src="/js/ui.bundle.js"></script>

</html>

A permits field on a sample user document on CouchDB user database is defined like below:

enter image description here


UPDATE:

Also this should be corrected too.

Community
  • 1
  • 1
user3405291
  • 5,371
  • 3
  • 32
  • 81

1 Answers1

1

this.user is not set when you declare your class, so this.user.permits will give rise to an error. You could do something like this instead:

class Store {
  @observable user
  @observable menus = []
  @action setUser = (user) => {
    this.user = user
    this.menus.push({
      menu1: 'DATABASE',
      menu2s: this.user.permits.db
    })
  }
}
Tholle
  • 83,208
  • 13
  • 152
  • 148
  • I tried but looks like the problem is related to how CouchDB pareses a field of a document. `console.log('user.permits: '+user.permits)` output is `user.permits: {db: ['TEL', 'PTT',]}` and `console.log('user.permits.db: '+user.permits.db)` shows `user.permits.db: undefined` – user3405291 Jan 24 '17 at 12:03
  • Therefore `user.permits` is good but `user.permits.db` cannot be accessed. – user3405291 Jan 24 '17 at 12:05
  • 1
    When combined with [this answer](http://stackoverflow.com/a/41829238/7312233), your solution worked, thanks! – user3405291 Jan 24 '17 at 13:37