Open Side Menu Go to the Top

06-30-2019 , 03:44 AM


Proof that all tech billionaires are visionary geniuses and not products of happenstance.

HURR DURR IT HAS NO KEYBOARD DURR MAYBE ONLY 5 PEOPLE IN THE WORLD WILL BUY IT DERP!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
06-30-2019 , 10:38 AM
I find it hard to believe that people think "add an auth server" is a simple solution to this problem - using base64 encoding is way preferable to that.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 12:48 PM
rusty: did you see my previous post (#38722)? It seems like it's what you want re: "I have an image tag, here's what data should go in it"

Or maybe I'm misunderstanding something.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 12:51 PM
Haha after hearing Suzzers cognito issues, how could you not just want another server doing Auth?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 02:12 PM
Quote:
Originally Posted by well named
rusty: did you see my previous post (#38722)? It seems like it's what you want re: "I have an image tag, here's what data should go in it"

Or maybe I'm misunderstanding something.
I did, but frankly I don't really understand it - it's operating at a much lower level than I usually have to drag myself to. I can probably find a way to wedge it into React but I consider that something of a last ditch. I am totally a hack javascript developer - I know the language fine but I spent zero time in the trenches before frameworks existed so I don't really know how to interact properly with the browser or the DOM or any of that nonsense.

I'm doing the encoding thing for now, if it annoys me more I can replace it in the future
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 03:02 PM
Quote:
Originally Posted by PJo336
Haha after hearing Suzzers cognito issues, how could you not just want another server doing Auth?
He said auth is required to serve the images. I took that to mean he already has a server with authentication built in for other API requests - he just wants to use it for images as well.

Grue and I are saying just create an end point in his existing API server - which works as a proxy to an image server. As opposed to trying to return a base64 blob from a separate rest api call, then somehow insert than into an image tag.

But as I said I can see a lot of cases where the former isn't that easy and maybe the latter is ok.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 05:31 PM
There is no image server - the API/backend is serving the images (and all other endpoints).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 07:46 PM
Are you currently serving any other images through this system which don't require auth?

Is your auth wired into the API/backend? Meaning like you can serve an end point with our w/o auth via a flag on the end point?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 07:53 PM
Yes, of course I can serve unauthenticated endpoints. The images in this particular case are authenticated for a reason - they're not public.

There's basically no way I'm going to use cookies for this. I toyed with the idea of using very short lived tokens for it (as url params), but that probably adds about the same level of dumb complexity as b64 encoding it, so /shrug
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 08:42 PM
Yeah if you can't use cookies or params then base64 is probably the way to go. In one of your posts you seemed to suggest cookies were possible.

I assume you're using tokens and an HTTP Authentication header? Here's an example of how to turn your Auth header into a cookie if you want: https://stackoverflow.com/questions/...n-img-src-link (the last answer). I agree with the previous answer that turning your auth header into a param on the img src link is a bad idea.

So barring any of that - yeah just load the base64 images over AJAX when the page loads - and then refer to them as the src in your image.

Here's a google base64 image:

Code:
<img 
class="target_image irc_rii" 
src="data:image/jpeg;base64,/9j/4AAQS ***SNIP*** 0FPqf/2Q==" 
alt="Related image" 
onload="typeof google==='object'&amp;&amp;google.aft&amp;&amp;google.aft(this)" 
data-iml="1561941496531" 
style="width: 160px; height: 80px; margin-left: -40px;"
>
Note, I've never dealt generating base64 on the fly - but it seems like you should just be able to set a react state variable as your image src when your api comes back with it. Just make sure to use the built in JS method atob() to un-encode it first.

I'm definitely curious to see what ends up working.

Last edited by suzzer99; 06-30-2019 at 08:50 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 08:43 PM
Yeah I've already implemented the encoded version, it's not hard. Just inelegant
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 09:01 PM
Can you post the code? I'm curious to see how it works. Does a react state variable as the img src property work?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 09:18 PM
I'll post it when I get home
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 10:00 PM
This is redacted a little for simplicity, I don't think I took anything out that would make it incomprehensible. The data I get back from the API is already base 64 encoded.

Code:
class PCBRender extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      img: '',
    };
  };

  componentDidMount() {
    this.updateImage()
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    if (prevProps === this.props) return
    this.updateImage()
  }

  updateImage() {
    if (this.props.project_key === null) {
      return
    }

    let fw = this.props.store.get('frameworks')
    fw.PCBApi.render({
      project_key: this.props.project_key,
      username: this.props.username,
      side: this.props.side,
    }).then(
      data => this.setState({img: 'data:image/jpeg;base64,' + data})
    )
  }

  render() {
    let { classes } = this.props
    let loading =  (this.props.project_key === null || !this.state.img.length)

    return (loading)
      ? <div>Loading</div>
      : <img src={this.state.img}/>
  }
}
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 10:21 PM
Yep pretty much how I would imagine. I just wasn't sure if react would be happy with the img src tag. Just out of curiosity did you try letting the image load with an empty src? I guess it makes a broken image icon on the page?

I'm not 100% sure about this though:

Code:
 componentDidUpdate(prevProps, prevState, snapshot) {
    if (prevProps === this.props) return
    this.updateImage()
  }
This is only going to tell if you if prevProps and this.props are both references to the exact same object - not equivalence.

Btw async await makes promises a ton cleaner:

Code:
async updateImage() {
  if (this.props.project_key === null) {
    return
  }

  let fw = this.props.store.get('frameworks')
  const data = await w.PCBApi.render({
    project_key: this.props.project_key,
    username: this.props.username,
    side: this.props.side,
  })

  this.setState({img: 'data:image/jpeg;base64,' + data})
}
You could theoretically put the whole await call in your setState call instead of creating the data variable. But that looks really clunky imo.

Last edited by suzzer99; 06-30-2019 at 10:28 PM.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 10:57 PM
Yeah I got broken images. In reality I don't print "loading", I have a little spinny loading icon, left it out for simplicity

I have used async/await before but I haven't set up this project to support it, I'll get around to it maybe.

Regarding the ===, that's what I thought, my editor nagged me to add the extra =. FWIW it seems to work, I guess probably because you get a new props every time, not a modified version of the old one? I actually find componentDidUpdate kind of annoying - I want the semantic equivalent of "we got new props"
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:27 PM
Extra === means nothing for objects. It just detects exact accuracy vs. "truthy" in strings, numbers etc. https://codeburst.io/javascript-show...s-7be792be15b5

What you probably need to do is something like this:

Code:
componentDidUpdate(prevProps, prevState, snapshot) {
  if (this.props.project_key && this.props.project_key !== prevProps.project_key) 
    this.updateImage()
}
And remove the line checking for project_key === null in your updateImage() method.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:42 PM
You might even be able to skip the componentDidUpdate method entirely by doing something like this:

Code:
class PCBRender extends React.Component {

  async updateImage(project_key) {
    if (!project_key || project_key === this.state.project_key) {
      return
    }
    await this.setState('project_key', project_key); // might be necessary to wait here to avoid endless looping

    let fw = this.props.store.get('frameworks')
    const data = await fw.PCBApi.render({
      project_key: this.props.project_key,
      username: this.props.username,
      side: this.props.side,
    }).then(
      data => this.setState({img: 'data:image/jpeg;base64,' + data})
    )
  }

  render() {
    const imgSrc = updateImage(this.props.project_key);
    let { classes } = this.props
    let loading =  (this.props.project_key === null || !this.state.img.length)
 
    return (loading)
      ? <div>Loading</div>
      : <img src={this.state.img}/>
  }
}
Although there's very likely some things wrong with that but you get the idea. The modern react-y way seems to be to trigger everything by changes to state or props referenced in the render method. Also constructors or pre-defining state aren't needed unless the default state values aren't null/blank/empty/etc.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:46 PM
Haha, it's funny how much of Rusty's code posts render as emojis in tapatalk android
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:49 PM
Quote:
Originally Posted by suzzer99
You might even be able to skip the componentDidUpdate method entirely by doing something like this:
I'm pretty sure this is frowned upon - it might trigger an actual warning. The render() function is not supposed to trigger anything that might change the state.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:49 PM
Quote:
Originally Posted by PJo336
Haha, it's funny how much of Rusty's code posts render as emojis in tapatalk android
I render a lot of emojis IYKWIM
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
06-30-2019 , 11:52 PM
Quote:
Originally Posted by RustyBrooks
I'm pretty sure this is frowned upon - it might trigger an actual warning. The render() function is not supposed to trigger anything that might change the state.
Oh yeah that's right. You could have updateImage() it just return the img data though instead of setting it as state. But your loading condition would need some tweaking. Also we can't store existing project_key as state.

Anyway the upshot is we have zero or very few componentDidUpdate in our code - we trigger everything by tying things in the render method to props values.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
07-01-2019 , 12:10 AM
In this particular case the user is selecting from different project_keys. I have to trigger the generation of an image based on that, and that has to happen outside of render. As far as I know, componentDidUpdate is my only real option.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
07-01-2019 , 01:13 AM
Well the way we generally do it is to have the project_key state stored in a parent component. In your case a parent to your user-interactive project_key selector component, and the PCBRender component. That state is updated by the user-interactive component and passed down as props to the PCBRender child component.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
07-01-2019 , 10:32 AM
OK so I tried making updateImage an async function, using await as in your example. Then in my render I return
<img src={this.updateImage()}>
but the problem is, updateImage is an async function so it returns a promise. What's the right way to handle that?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m