samdenty / console-feed

Captures console.log's into a React Component 🔥
https://stackblitz.com/~/github.com/samdenty/console-feed
MIT License
670 stars 109 forks source link

Not detecting console logs for online editor #49

Closed ChristopherHButler closed 4 years ago

ChristopherHButler commented 4 years ago

I am developing an online code editor (similar to codesandbox.io) and I am trying to incorporate console-feed after reading codesandbox use it however it does not seem to detect console.log statements in the editor even though I see the console logs in google chrome. I've followed your README to setup console-feed... Is there some extra or special configuration I need to do to get it to work in this way? Here is my code:

// code editor component. // setConsoles updates an array in redux.

...
  useEffect(() => {
    Hook(window.console, log => setConsoles({ log }), false);
    return () => Unhook(window.console);
  }, []);

// reducer

...
  [actions.setConsoles]: (state, { payload: { log } }) => {
    return {
      ...state,
      consoles: [...state.consoles, log],
    };
  },

// console component - consoles comes from reducer state

...
return (
  <ConsoleFeed logs={consoles} variant="dark" />
);
samdenty commented 4 years ago

It sounds like you're trying to capture the logs of an iframe.

To do that, you'd have to use postmessage / onmessage

// Inside the iframe's context, bundled with webpack / something
Hook(window.console, log => {
  self.postMessage({type: 'log', log})
});
// In your editor
window.addEventListener('message', ({data}) => {
if (data.type === 'log') {
  setConsoles({ log: Decode(data.log) })
}
})
ChristopherHButler commented 4 years ago

Ok I got it to work, Thanks @samdenty!!

I get a reference to the iFrame and used that when setting the hook. (I should probably mention my app is written in React). Anyways, for anyone else that comes across this, here is the relevant code for what I did:

// In component with iFrame
...
  // ref to iFrame
  const ref = useRef();
  const [hooked, setHooked] = useState(false);

  useEffect(() => {
    const iWindow = ref.current.contentWindow;

    createViewerOutput(compiledCode);

    return () => Unhook(iWindow.console);

  }, [compiledCode]);

  const createViewerOutput = (contents) => {
  ...
  const iWindow = ref.current.contentWindow;

  if (!hooked) {
    setHooked(true);
    Hook(iWindow.console, log => setConsoles({ log }), false);
  }
...