Henry Puspurs
Henry Puspurs

Reputation: 106

Blazor WebAssembly not making HttpClient call on click

So I use ASP.NET a lot and thought I'd have a go at blazor for fun. So I'm using WebAssembly client only, trying to create a search view using the free tier bing api.

Thing is every time I hit the HttpClient GetAsync method, the whole page reloads. So, this is the view

@page "/"
@inject ApiCallHandler Handler

<div class="flex-wrap d-md-inline-block">
    <form Model="@searchString">
        <span>
            <input type="text" class="form-text" value="@searchString" />
            <button type="submit" class="btn btn-primary" @onclick="Search">Search</button>
        </span>
    </form>

    @if (imageResponse == null)
    {

    }
    else
    {
        if (imageResponse.IsSuccess == false)
        {
            <p>Unable to fetch images</p>
        }
        <div class="flex-wrap align-content-center">
            @for (int i = 0; i < imageResponse.Value.Count(); i++)
            {
                var image = imageResponse.Value[i];
                <img class="thmb" src='@image.ThumbnailUrl' />
            }
        </div>
    }
</div>

@code {
    private ImageResponseModel imageResponse;

    public string searchString { get; set; }

    private async Task Search()
    {
        imageResponse = await Handler.ImageSearch(searchString);
    }
}

And this is the handler thats referenced.

using BingSearch.Models;
using BingSearch.Models.ResponseModels;
using Microsoft.AspNetCore.Components;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Threading.Tasks;

namespace BingSearch.Services
{
    public class ApiCallHandler
    {
        private HttpClient _client;

        public ApiCallHandler()
        {
            _client = new HttpClient() { BaseAddress = new Uri("https://api.bing.microsoft.com/v7.0/images/search") };
            _client.DefaultRequestHeaders.Add("Ocp-Apim-Subscription-Key", "MyKeyYouCantHaveIt!");
        }

        public async Task<ImageResponseModel> ImageSearch(string searchString)
        {
            searchString = searchString.Replace(" ", "+");

            var response = await _client.GetAsync($"?q={searchString}&count=10");

            if (response.IsSuccessStatusCode)
            {
                var imageResponse =  JsonConvert.DeserializeObject<ImageResponseModel>(await response.Content.ReadAsStringAsync());
                imageResponse.IsSuccess = response.IsSuccessStatusCode;
                return imageResponse;
            }
            else
            {
                return new ImageResponseModel() { IsSuccess = response.IsSuccessStatusCode};
            }
        }
    }
}

Basically I've been trying to throw it together using the original blazor template as the inspiration but then basically stripping it right back to return just some images. I had it working fine with protected override async Task OnInitializedAsync() hardcoded to bring up some results. But it just will not work being called from a click! in fact when I had both up, and set a default for searchString, it would bring up the default results, when I change it and click submit, passes my new search string to my handler, but again, reloads, and brings up the default results instead.

I've also tried using @bind and @bind-value instead of value=""

I realise the above code is far from optimal but I always work on the principles of get it working first, then make it pretty.

Upvotes: 1

Views: 786

Answers (1)

Henk Holterman
Henk Holterman

Reputation: 273179

<button type="submit" class="btn btn-primary" @onclick="Search">Search</button>

should be

<button type="button" class="btn btn-primary" @onclick="Search">Search</button>

A plain <form> does not support Model= but you should be able to use @bind-value. Just using value= is for JavaScript.

<form >
    <span>
        <input type="text" class="form-text" @bind-value="@searchString" />
        <button type="button" class="btn btn-primary" @onclick="Search">Search</button>
    </span>
</form>

Upvotes: 1

Related Questions