Coder Social home page Coder Social logo

this.coordinator.activate() is async. So, should there be an example of building a dataStore when you need the dataStore to be built about react-orbitjs HOT 7 CLOSED

exivity avatar exivity commented on May 26, 2024
this.coordinator.activate() is async. So, should there be an example of building a dataStore when you need the dataStore to be built

from react-orbitjs.

Comments (7)

hongaar avatar hongaar commented on May 26, 2024 3

Basically all react-orbitjs does is only ever query the stores cache. This will (intentionally for now, also refer to previously mentioned issue) never invoke any coordinators. This is to prevent unnecessary calls to your API when your component receives new props. Instead, you should specifically query your store directly using store.query (or the passed-down prop queryStore) to invoke a 'regular' query, which in turn will update the stores cache, which in turn will trigger react-orbitjs.

Try adding

inMemory.query(q => q.findRecord({ type: 'user', id: 'current-user' }));

right after await this.coordinator.activate();

There's a small note in the docs, but maybe I should update it:

Please note that withData() passes props received from the store cache. If you want to pull data from external sources, use the injected this.props.queryStore() method.

Also, adding a simple example app using a coordinator and external source would be nice. Who knows about a nice public JSON-API?

from react-orbitjs.

hongaar avatar hongaar commented on May 26, 2024

I think we're missing the withCurrentUser code to see what exactly is going on. Does it render inside the RootRoute component?

Also, where is the APIProvider rendered exactly?

And... what is your question exactly? 😉

from react-orbitjs.

NullVoxPopuli avatar NullVoxPopuli commented on May 26, 2024

withCurrentUser is:

import * as React from 'react';
import { Redirect } from 'react-router-dom';
import { withData, WithDataProps } from 'react-orbitjs';
import { compose } from 'recompose';
import { UserAttributes, TYPE_NAME } from '@data/models/user';
import { MapRecordsToProps } from '../../types/react-orbitjs/index';

type UserPayload = JSONAPI<UserAttributes>;

const mapRecordsToProps = {
  currentUser: q => q.findRecord({ id: 'current-user', type: TYPE_NAME })
}

interface IProps {
  currentUser: UserPayload;
}

interface IState {
  currentUser: UserPayload;
  notFound: boolean;
}

export function withCurrentUser() {
  return InnerComponent => {
    class WrapperClass extends React.Component<IProps & WithDataProps, IState> {
      state = { currentUser: undefined, notFound: false };

      componentDidMount() {
        const { currentUser } = this.props;

        if (currentUser) {
          this.setState({ currentUser });
          return;
        }

        // There is no current user. Redirect to login.
        // NOTE: because the backend does findOrCreate with the
        //     auth0Id, this should never happen.
        //     but it could if the network request fails or
        //     if there is a server error.
        //
        // TODO: store the attempted URL so that after login,
        //     we can navigate back.
        this.setState({ notFound: true });
      }

      render() {
        const { currentUser, notFound } = this.state;

	console.debug('current user: ', this.state);

        if (currentUser) {
          return <InnerComponent {...this.props} />;
        } else if (notFound) {
          return 'User could not be found and/or created....';
          return <Redirect to={'/login'} />;
        }

        return 'Loading? what should we do here before we get the current user?';
      }
    }

    return compose(
      withData(mapRecordsToProps)
    )(WrapperClass);
  }
}

which is then used within:
requireAuth

import * as React from 'react';
import { withRouter, RouterProps, Redirect } from 'react-router';

import { withCurrentUser } from '@data/with-current-user';
import { isLoggedIn } from '@lib/auth0';
import * as toast from '@lib/toast';

import { pathName as loginPath } from '@ui/routes/login';

export function requireAuth(Component) {
  const checkForAuth = (propsWithRouting: RouterProps) => {
    const authenticated = isLoggedIn();

    if (authenticated) {
      const WithUser = withCurrentUser()(Component);

      return <WithUser { ...propsWithRouting } />;
    }

    // toast.error('You must be logged in to do that');

    return <Redirect to={loginPath} />;
  };

  return requireAuthHelper(checkForAuth);
}

export function requireNoAuth(redirectPath = '/') {
  return (Component) => {
    const checkForNoAuth = (propsWithRouting: RouterProps) => {
      const authenticated = isLoggedIn();

      if (!authenticated) {
        return <Component { ...propsWithRouting } />;
      }

      // toast.error('You must be logged out to do that');

      return <Redirect to={redirectPath} />;
    };

    return requireAuthHelper(checkForNoAuth);
  };
}

function requireAuthHelper(authenticationChecker: (props: RouterProps) => any) {
  return (props: any) => {
    if (props.history) {
      return authenticationChecker(props);
    }

    const WrappedWithRouter = withRouter(authenticationChecker);

    return <WrappedWithRouter {...props } />;
  };
}

which is then used here:

import * as React from 'react';
import { compose } from 'recompose';

import { requireAuth } from '@lib/auth';
import { withLayout } from '@ui/components/layout';

export const pathName = '/tasks';

class Tasks extends React.Component {

  state = { data: {}, errors: {} };

  render() {
    return 'hi';
  }
}

export default compose(
  withLayout,
  requireAuth
)(Tasks);

(sorry for the redirection -- lots of abstracting going on here)

The APIProvider? do you mean the DataProvider? -- in application.tsx, which is rendered from here:

import * as React from 'react';
import * as ReactDOM from 'react-dom';

import 'vendor/legacy-support';
import './global-config';

import 'semantic-ui-css/semantic.min.css';

import './ui/styles/app.scss';
// require('public/images/*');

import Application from './ui/application';

ReactDOM.render(
  <Application />,
  document.getElementById('root')
);

(and that's the entrypoint to my app)

And... what is your question exactly? 😉

I'm just wondering if there should be a more thorough example? since maybe the store's setup requires async behavior? and the readme assumes that the dataStore already exists, which is fine, maybe -- but with react handling async things always requires a placeholder component (at least, I'm pretty sure it does). :-\

from react-orbitjs.

hongaar avatar hongaar commented on May 26, 2024

Do you call inMemory.query somewhere? Maybe you're looking at the problem described in more detail here #4?

from react-orbitjs.

NullVoxPopuli avatar NullVoxPopuli commented on May 26, 2024

I "think" so? I'm still pretty new to orbit.

In all that mess I have pasted above, this is my only query:

const mapRecordsToProps = {
  currentUser: q => q.findRecord({ id: 'current-user', type: TYPE_NAME })
}

and orbit is printing this warning:
image

from react-orbitjs.

NullVoxPopuli avatar NullVoxPopuli commented on May 26, 2024

thanks!

Also, as far as public JSONAPIs, I found this:
http://thomaxxl.pythonanywhere.com/api/#!/Users/RetrieveaUserobject_0

http://thomaxxl.pythonanywhere.com/Users/?page[limit]=10&include=books&sort=name%2Cemail%2Ccomment

from react-orbitjs.

hongaar avatar hongaar commented on May 26, 2024

Thanks, I will have a look.

Closing this now, but feel free to comment here if you need more help!

from react-orbitjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.