Skip to content
This repository was archived by the owner on Dec 18, 2019. It is now read-only.
This repository was archived by the owner on Dec 18, 2019. It is now read-only.

Help needed - MemoryStream.map not producing output #51

@ca057

Description

@ca057

Hey,

I hope this is the right place to ask for help. I'm currently trying to get started with CycleJS and cycle-onionify and have troubles getting my app to produce the right output. Currently it is a simple input field, on every enter a message object is created and should then be rendered in a list. With starting to split that into multiple, smaller components, I see no output of my message list anymore (only my input field). To be more specific: I can log the list of messages (which contain the correct amount of messages) and in my Message-component I also get a log output for the sources, so the code is at least touched (means: 2 messages in the list, 2 logs in my console; 3 when I add one more message and so on).

My Message-component looks like the following:

import xs from 'xstream';
import { div, p } from '@cycle/dom';
import isolate from '@cycle/isolate';

const calculateTimeString = timestamp => {
  const date = timestamp && new Date(timestamp);
  return `${date.toLocaleDateString()}: ${date.toLocaleTimeString()}`;
};

function Message(sources) {
  const state$ = sources.onion.state$;
  console.log(state$); // --> logs a MemoryStream

  const vdom$ = state$.map(state => {
    // HELPME this does not produce any output
    console.log('Message', state);
    return div('.messageItem', [
      p(calculateTimeString(state.time)),
      p(state.message),
    ]);
  });
  return {
    DOM: vdom$,
    onion: xs.empty(),
  };
}

// (sources) => ...
export default isolate(Message);

and is integrated into the following MessageList:

import { ul } from '@cycle/dom';
import isolate from '@cycle/isolate';
import { pick, mix } from 'cycle-onionify';
import xs from 'xstream';

import Message from './../Message';

function MessageList(sources) {
  const state$ = sources.onion.state$;

  const childrenSinks$ = state$.map(messages => {
    // --> with every new message, this logs me the array of messages [{...}, {...}, ...]
    console.log('MessageList', messages);
    return messages.map((msg, i) => {
      return isolate(Message, i)(sources);
    });
  });
  const vdom$ = childrenSinks$
    .compose(pick(sinks => sinks.DOM))
    .compose(mix(xs.combine))
    .map(ul);

  const reducer$ = childrenSinks$
    .compose(pick(sinks => sinks.onion))
    .compose(mix(xs.merge));

  return {
    DOM: vdom$,
    onion: reducer$,
  };
}

export default MessageList;

For the sake of completeness, everything is integrated into this main app:

import xs from 'xstream';
import { div, p, input } from '@cycle/dom';
import isolate from '@cycle/isolate';
import { prepend } from 'ramda';

// FIXME how to strcutre components? why not automatically importing index?
import MessageList from './components/MessageList/index';

function intent(domSource) {
  return domSource
    .select('.message')
    .events('keydown')
    .filter(({ keyCode, target }) => keyCode === 13 && target.value !== '')
    .map(ev => {
      const val = ev.target.value;
      // eslint-disable-next-line no-param-reassign
      ev.target.value = '';
      return {
        time: Date.now(),
        message: val,
      };
    });
}

function model(action$) {
  const initReducer$ = xs.of(() => ({ messages: [] }));
  const updateReducer$ = action$.map(message => prevState => ({
    messages: prepend(message, prevState.messages),
  }));
  return xs.merge(initReducer$, updateReducer$);
}

export default function App(sources) {
  const messageListSinks = isolate(MessageList, 'messages')(sources);

  const action$ = intent(sources.DOM);
  const parentReducer$ = model(action$);
  const messageListReducer$ = messageListSinks.onion;
  const reducer$ = xs.merge(parentReducer$, messageListReducer$);

  const vtree$ = messageListSinks.DOM.map(listNode =>
    div([
      p('Eingabe einer neuen Nachricht:'),
      input('.message', { attrs: { type: 'text', autofocus: true } }),
      listNode,
    ])
  );

  return {
    DOM: vtree$,
    onion: reducer$,
  };
}

Am I missing something? Am I doing something wrong? I tried to stick to the example here in the repo, but cannot find my error.

Hope one of you can help me out, in case you need more infos or the whole source-code, please let me know!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions