Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

302
Visualizações
Alpinejs async computed property with spinner

I have a range slider input, which should trigger an async computed property to display. While it is waiting on the response, I want to display a spinner. See below what I came up with. I sense I over complicate things and sometimes both the spinner and the resulting title displays at the same time (!). Is there a better way of doing async computed props with Alpinejs?

<script src="//unpkg.com/alpinejs" defer></script>

<script>
  async function getTitle(id) {
    const response = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
    const data = await response.json();

    await new Promise(resolve => setTimeout(resolve, 2500)) // adds some extra slowness

    return data.title.toUpperCase()
  }
</script>

<div x-data="{ todoId: 10, title: 'A PRELODED TODO TITLE' }">
    <h3>Title formatter</h3>
    <p>Grab a todo via API and uppercases title </p>
    <input x-model="todoId" x-on:change="console.log('change!'); title = null" id="steps-range" type="range" min="0" max="50" step="1">
    <div x-show="title !== null" x-html="title ?? (title = (await getTitle(todoId)))"></div>
    <div x-show="title === null">Loading ...</div>
</div>

JSFIDDLE

about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

I have adjusted your example in order to show a different way to handle the same problem, It's simplified on the Alpine.js side and I've adjusted your function in order to assist the label problem.

<script src="//unpkg.com/alpinejs" defer></script>
<style>
  .error {
    color: red;
  }
  
  .success {
    color: blue;
  }
  
  .loading {
    color: orange;
  }
</style>
<div x-data="{
          todoId: 10,
          title: 'A PRELODED TODO TITLE',
          error: false,
          loading: false,
                async getTitle(id) {
              this.success = true
              this.error = false
              this.loading = true
                this.title = 'Loading ...'
                    await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`)
                    .then(res => res.json())
                    .then(async(res) => {
                    await new Promise(resolve => setTimeout(resolve, 100)) // adds some extra slowness
                if(res.id === parseInt(this.todoId)) {
                  this.loading = false
                  this.success = true
                    this.title = res.title.toUpperCase()
                 }
                return
                    }).catch((e) => {
                  this.loading = false
                  this.title = e.message
                  this.error = true
              })
            }

}" x-init="$watch('todoId', (newValue, oldValue) => {
                    newValue != oldValue ? $nextTick(async() => { getTitle(todoId) }) : null
               })">
  <h3>Title formatter</h3>
  <p>Grab a todo via API and uppercases title</p>
  <input x-model="todoId" id="steps-range" type="range" min="0" max="50" step="1" />
  <div x-show="title" :class="{'error': error, 'success': !error, 'loading': loading}" x-text="title"></div>
</div>

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda