Back to Wails

Dogs API

website/versioned_docs/version-v2.12.0/tutorials/dogsapi.mdx

2.12.04.9 KB
Original Source

Dogs API

mdx-code-block
<div class="text--center">
  
</div>


:::note

This tutorial has been kindly provided by @tatadan and forms part of their Wails Examples Repository.

:::

In this tutorial we are going to develop an application that retrieves photos of dogs from the web and then displays them.

Create the project

Let's create the application. From a terminal enter: wails init -n dogs-api -t svelte

Note: We could optionally add -ide vscode or -ide goland to the end of this command if you wanted to add IDE support.

Now let's cd dogs-api and start editing the project files.

Remove unused code

We will start by removing some elements that we know we will not use:

  • Open app.go and remove the following lines:
go
// Greet returns a greeting for the given name
func (a *App) Greet(name string) string {
	return fmt.Sprintf("Hello %s, It's show time!", name)
}
  • Open frontend/src/App.svelte and delete all lines.
  • Delete the frontend/src/assets/images/logo-universal.png file

Creating our application

Now let's add our new Go code.

Add the following struct declarations to app.go before the function definitions:

go
type RandomImage struct {
	Message string
	Status  string
}

type AllBreeds struct {
	Message map[string]map[string][]string
	Status  string
}

type ImagesByBreed struct {
	Message []string
	Status  string
}

Add the following functions to app.go (perhaps after the existing function definitions):

go
func (a *App) GetRandomImageUrl() string {
	response, err := http.Get("https://dog.ceo/api/breeds/image/random")
	if err != nil {
		log.Fatal(err)
	}

	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}

	var data RandomImage
	json.Unmarshal(responseData, &data)

	return data.Message
}

func (a *App) GetBreedList() []string {
	var breeds []string

	response, err := http.Get("https://dog.ceo/api/breeds/list/all")
	if err != nil {
		log.Fatal(err)
	}

	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}

	var data AllBreeds
	json.Unmarshal(responseData, &data)

	for k := range data.Message {
		breeds = append(breeds, k)
	}

	sort.Strings(breeds)

	return breeds
}

func (a *App) GetImageUrlsByBreed(breed string) []string {

	url := fmt.Sprintf("%s%s%s%s", "https://dog.ceo/api/", "breed/", breed, "/images")
	response, err := http.Get(url)
	if err != nil {
		log.Fatal(err)
	}

	responseData, err := ioutil.ReadAll(response.Body)
	if err != nil {
		log.Fatal(err)
	}

	var data ImagesByBreed
	json.Unmarshal(responseData, &data)

	return data.Message
}

Modify the import section of app.go to look like this:

go
import (
	"context"
	"fmt"
	"encoding/json"
	"io/ioutil"
	"log"
	"net/http"
	"sort"
)

Add the following lines to frontend/src/App.svelte:

<!-- prettier-ignore-start -->
html
<script>
  import { GetRandomImageUrl } from "../wailsjs/go/main/App.js";
  import { GetBreedList } from "../wailsjs/go/main/App.js";
  import { GetImageUrlsByBreed } from "../wailsjs/go/main/App.js";

  let randomImageUrl = "";
  let breeds = [];
  let photos = [];
  let selectedBreed;
  let showRandomPhoto = false;
  let showBreedPhotos = false;

  function init() {
    getBreedList();
  }

  init();

  function getRandomImageUrl() {
    showRandomPhoto = false;
    showBreedPhotos = false;
    GetRandomImageUrl().then((result) => (randomImageUrl = result));
    showRandomPhoto = true;
  }

  function getBreedList() {
    GetBreedList().then((result) => (breeds = result));
  }

  function getImageUrlsByBreed() {
    init();
    showRandomPhoto = false;
    showBreedPhotos = false;
    GetImageUrlsByBreed(selectedBreed).then((result) => (photos = result));
    showBreedPhotos = true;
  }
</script>

<h3>Dogs API</h3>
<div>
  <button class="btn" on:click={getRandomImageUrl}>
    Fetch a dog randomly
  </button>
  Click on down arrow to select a breed
  <select bind:value={selectedBreed}>
    {#each breeds as breed}
      <option value={breed}>
        {breed}
      </option>
    {/each}
  </select>
  <button class="btn" on:click={getImageUrlsByBreed}>
    Fetch by this breed
  </button>
</div>


{#if showRandomPhoto}
  
{/if}
{#if showBreedPhotos}
  {#each photos as photo}
    
  {/each}
{/if}

<style>
  #random-photo {
    width: 600px;
    height: auto;
  }

  #breed-photos {
    width: 300px;
    height: auto;
  }

  .btn:focus {
    border-width: 3px;
  }
</style>
<!-- prettier-ignore-end -->

Testing the application

To generate the bindings and test the application, run wails dev.

Compiling the application

To compile the application to a single, production grade binary, run wails build.