Random unsplash image throws error

hi, trying to implement Random Unsplash Image in Svelte, here’s the app.svelte:
REPL here:

<script>
  const clientID = `74tPSBlBDFDflVT_6_PsoTJNbVD2XF0qBLhE3Qo83Yo`;
  const endpoint = `https://api.unsplash.com/photos/random?client_id=${clientID}`;
  
  let imageElement = document.querySelector(`#unsplashImage`);
  let imageLink = document.querySelector("#imageLink");
  let creator = document.querySelector("#creator");
  fetch(endpoint)
    .then((response) => response.json()) 
     .then((jsonData) => {
      imageElement.src = jsonData.urls.regular;
      imageLink.setAttribute("href", jsonData.links.html);
      creator.innerHTML = jsonData.user.name;
      creator.setAttribute("href", jsonData.user.portfolio_url);
    })
    .catch ((error) => {
      console.log("Error: " + error);
    });
  </script>
  
  <main>
     <h1>Random Unsplash Image</h1>
    <div class="imageContainer">
      <a id="imageLink" href="#top">
        <img alt="" id="unsplashImage" />
      </a>
    </div>
    <p class="imageDetails">Photo by <a id="creator" href="#top">NAME</a> on 
      <a href="https://www.unsplash.com">Unsplash</a>!</p>
  </main>
  
  <style>
    main {
      min-width: 100%;
      background-color: yellow;
      text-align: center;
      font-family: sans-serif;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
  
    #unsplashImage {
      max-height: 500px;
      border: 20px solid black;
      transform: rotate(3deg);
    }
  
    h1 {
      font-size: 56px;
    }
  
    .imageDetails {
      background-color: black;
      margin-top: 50px;
      padding: 10px;
      color: white;
      text-decoration: none;
      font-weight: bold;
      width: fit-content;
    }
  
    .imageDetails a {
      color: #FFF;
    }
  
    .imageDetails a:hover {
      color: yellow;
    }
  
  </style>  

this line:
imageElement.src = jsonData.urls.regular;

Throws error:
“Error: TypeError: Cannot set properties of null (setting ‘src’)”
Any help solving this greatly appreciated

Hi David! Welcome to the forums :slight_smile:

You are accessing the image element from JavaScript before your code is aware of it. This is one of those moments where the location of your HTML and JS in the document plays an important role.

The solution is to move your script tag and all of the code to below where you have your HTML elements defined. This will ensure our browser is aware of the HTML content and can give our JavaScript references to the HTML content the correct details.

I cover this in more detail in these two articles: Where Should Your Code Live | KIRUPA and Running Your JavaScript at the Right Time

:partying_face:

Hi, thanks for your reply.
This is a Svelte app, which I’m trying to learn.
This intro says

All three sections — <script>, <style>, and markup — are optional, and can appear in any order you like.

<script>
  // logic goes here
</script>

<style>
  /* styles go here */
</style>

<!-- markup (zero or more HTML elements) goes here -->
So I think the order doesn't matter

First up a usual disclaimer pointing out that I dont use Svelte and dont have much knowledge of it. I just looked up a few things to get an answer for you.

If this was normal js then yeah, just putting the js below would have fixed things because the html would have been rendered before the js executed, but this is Svelte. This code will be compiled into something else and so the order things are executed in is not determined by the placement in the file. You can see this if you look at the JsOutput tab. With all these things there is usually a Life Cycle that determines when things happen and you tap into that. With Svelte what you want is the onMount event, whatever is in that event will happen after your html has been rendered to the DOM. Check this doc…

So with that in mind if we put all your current code in an onMount event then things work…

Whilst looking at this noticed that you can avoid querySelector if you want, so did that aswell…

Now you should look at converting that into its own component :stuck_out_tongue_winking_eye:

Thanks PAEz for taking the time to check out Svelte and explain it to me, much appreciated.
I’m an old newbie to this - started back in the 80’s, created alot of magic with COBOL connecting DOS based systems to the web - was attracted to Svelte 'cause it’s also compiled and COBOL programs are divided into sections - File io, storage, procedure - but all these new packets just seem to add another level of complexity, and it’s hard for my old brain to grasp.
The point of Random Unsplash Image tutorial was that each click produced a new image, any idea how i’d do that with your solution?
Thanks

Yeah sure I can give that a go…

I moved the splash loading code into its own function, then made that function run on onMount and when you click the background of the page (main). There could certainly be better ways of doing it, I wouldnt know, dont have any experience with it.

Hehe, another oldie. I was doing machine code on the c64 in the 80’s then AMOS on Amiga. Couldnt handle languages like COBOL, C and the like. Tried for years to do pascal, made lots of stuff but REALLY didnt understand a LOT of it :stuck_out_tongue_winking_eye: . Then I found JS and LOVED it!!! Decided it would prolly be the best for the future because of all the awesome apis in the browser and its truly all platform. And then Chrome got V8, I saw it beat Delphi (a compiled language) at rendering a mandlebrot and that was the end of that :stuck_out_tongue_winking_eye:

Oh, and welcome to the forums! Hope we can all help you enjoy JS as much as we do.

1 Like

Hi PAEz, Thanks very much for this.
In vscode the whole main section throws the error (underlined):

A11y: visible, non-interactive elements with an on:click event must be accompanied by an on:keydown, on:keyup, or on:keypress event.

I see in your Svelte Unsplash CodeSandbox there’s a Button.svelte component but it’s not used in App.svelte, could that be the problem?

Before I get into Svelte I need to develop my JavaScript skills, but was wondering what you (coming from the same era ) would recommend as a good development environment?
Thanks

Fumbling around with your last version, this REPL seems to be going in the right direction, problem now is that when clicked a second window opens with the current image, if you close this, app.svelte displays the next random image correctly. Any ideas how to stop the second screen from displaying?

Sorry for the late reply, sometimes I cant do anything for a while.

I wasnt sure what behavior you wanted so made the change on background click not picture because it already had some. Heres the change plus I redid the code to be more svelte like. In the first one I did it from a vanilla js perspective where the js gets the data and puts it in the html/dom, whereas in this one the js gets the data and the html knows where to get it from, its just a template. Hehe, I dont know how to explain this stuff, hopefully the code does that.

A11y: If I remember right thats a accessibility thing, making pages work better for the blind and what not. I added in a fix but not sure whats the point as the elements not select able but maybe its to do with screen readers or wot not. It was looking for keyboard input to compliment the click input I put on the image. Always good to cover this stuff, its not much hassle and Ive lived with blind kids, nuts the level they go through to make things work for themselves.

Environment: Not sure what you mean by that? If its what I use to code its VsCode because its awesome. I tried this in there with three extensions ( svelte for VS Code, svelte format and svelte preview) and it was great. If your talking what code stuff I just do vanilla js for fun.

Hi PAEz, good to hear from you. I’ve been working on this Sveltejs repl
I’m now trying to move onto Sveltekit (without TypeScript) 'cause that seems to be the way to develop a proper svelte site - but maybe I’m just making life difficult for myself. Anyway the point of this site is to help develop the users Remote Viewing skills (and my Svelte programming skills) this lady explains what it is, Stephan Shwartz is also an interesting guy to listen to on the subject.
So my idea was to present 4 hidden images and let the user try and describe what the hidden image is before opening it, it’s still just an idea and I don’t have the page templates worked out yet. Like to hear what you think.

Now have a working Remote Viewing Repl.
Hope all’s well with you.
Thanks for your help

1 Like