No tienes acceso a esta clase

¡Continúa aprendiendo! Únete y comienza a potenciar tu carrera

Mostrando lista de productos

13/19
Recursos

Aportes 19

Preguntas 5

Ordenar por:

¿Quieres ver más aportes, preguntas y respuestas de la comunidad?

A mi al final no me funciono, tal cual se muestra, realice unas modificaciones, hasta lograr que operará, no se si les es de utilidad, pero, comparto el codigo final que en mi caso funciono:

Code:

@page “/product”
@inject ILogger<Products> logger;
@inject IProductService producService;

<PageTitle>Products</PageTitle>

<ModuleTitle Title=“Products”/>

@if (Visible == true)
{
@if (products?.Count > 0)
{
<div class= “products-container”>
@foreach (var product in products)
{
<div class=“card”>
<img class=“card-img-top” src="@product.Images[0]" alt=“Product” loading=“lazy” width = “270” height=“210”>
<div class=“card-body”>
<h4><b>@product.Title</b></h4>
<p>@product.Price?.ToString(“C”)</p>

                </div>
            </div>
        }
    </div>
}
else
{
    <p>No hay productos para mostrar</p>
}

}

@code {
private List<Product>? products;
private bool Visible { get; set; }

private async Task<List<Product>> GetProducts()
{
    return await producService.Get();
}

protected override async void OnInitialized()
{
    Visible = false;
    products = await GetProducts();
    Visible = true;
    StateHasChanged();
}



 //@* <button title="Eliminar" class="btn btn-danger btn-delte" @onclick=@(() => Delete(product))"><span class="oi oi-trash></span></button>*@

}

al realizar la pruebas de obtener datos, no retorno por que se arma mal la ruta; deje el servicio asi:   var response = await client.GetAsync("/api/v1/products"); y el appsettings asi :     "apiUrl":"https://api.escuelajs.co" a demas la api retorna las propiedades en minuscula , entonces ajuste el modelo asi public class Product{        public int Id { get; set; }        public string title { get; set; }        public decimal? price { get; set; }        public string description { get; set; }        public int categoryId { get; set; }        public string\[] images { get; set; }        public string? image { get; set; }} todo esto en net 8.0

Si les falla esta linea private List<Product> products;, es por que les hace falta un using que es ejemplo el suguiente:

@using BlazorAppVisualStudio.Models;

Si crear las siguientes 2 lineas en el archivo _Imports.razor, no volveran a preocuparce por esos using al momento de crear sus pages:

@using BlazorAppVisualStudio.Services;
@using BlazorAppVisualStudio.Models;

get de productService.css

public async Task<List<Product>?> Get(){
        var response=await client.GetAsync("/v1/products");
        var content= await response.Content.ReadAsStringAsync();
        if (!response.IsSuccessStatusCode)
        {
            throw new ApplicationException(content);
        }
        return JsonSerializer.Deserialize<List<Product>>(content,option);
    }
Gravedad Código Descripción Proyecto Archivo Línea Estado suprimido Error (activo) CS0029 No se puede convertir implícitamente el tipo 'System.Collections.Generic.List\<BlazorAppVisualstudio.Models.Product>' en 'System.Collections.Generic.List\<BlazorAppVisualstudio.Pages.Product>' BlazorAppVisualstudio C:\Proyectos\Practicas\\.netBlazor\BlazorAppVisualstudio\Pages\Product.razor 25 me esta dando este error @page "/product" @using BlazorAppVisualstudio.Services @using BlazorAppVisualstudio.Models @inject ILogger\<Product> logger; @inject IProductServices productServices; \<PageTitle>Products\</PageTitle> \<ModuleTitle Title="Products" /> @code { private List\<Product>? products; protected override async Task OnInitializedAsync() { products = await GetProducts(); } private async Task\<List\<Product>> GetProducts() { return await productServices.Get(); } }
```js @page "/product" @using BlazorAppVisualstudio.Services @using BlazorAppVisualstudio.Models @inject ILogger<Product> logger; @inject IProductServices productServices; <PageTitle>Products</PageTitle> <ModuleTitle Title="Products" /> @code { private List<Product>? products; protected override async Task OnInitializedAsync() { products = await GetProducts(); } private async Task<List<Product>> GetProducts() { return await productServices.Get(); } } ``````js using BlazorAppVisualstudio; using BlazorAppVisualstudio.Services; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); builder.RootComponents.Add<HeadOutlet>("head::after"); var apiUrl = builder.Configuration.GetValue<string>("apiUrl"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(apiUrl) }); builder.Services.AddScoped<IProductServices, ProductServices>(); builder.Services.AddScoped<ICategoryService, CategoryService>(); await builder.Build().RunAsync(); ```using BlazorAppVisualstudio; using BlazorAppVisualstudio.Services; using Microsoft.AspNetCore.Components.Web; using Microsoft.AspNetCore.Components.WebAssembly.Hosting; var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add\<App>("#app"); builder.RootComponents.Add\<HeadOutlet>("head::after"); var apiUrl = builder.Configuration.GetValue\<string>("apiUrl"); builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(apiUrl) }); builder.Services.AddScoped\<IProductServices, ProductServices>(); builder.Services.AddScoped\<ICategoryService, CategoryService>(); await builder.Build().RunAsync(); }
hola a todos saludos estuve haciendo los de categoría pero al llegar al modificar me surgió una duda, no conseguí un método que realizara la modificación, surgió la duda ```js public async Task Update(int CategoriyId, Category category) { var reponse = await _client.PutAsync("v1/categories", "aca que coloco"); var content = await reponse.Content.ReadAsStringAsync(); if (!reponse.IsSuccessStatusCode) { throw new ApplicationException(content); } } ```` public async Task Update(int CategoriyId, Category category)` ` {` ` var reponse = await _client.PutAsync("v1/categories", );` ` var content = await reponse.Content.ReadAsStringAsync();` ` if (!reponse.IsSuccessStatusCode)` ` {` ` throw new ApplicationException(content);` ` }` ` }`
Para los que tengan error, puede ser porque ahora la API de fake storage devuelve el json con unos valores diferentes a los utilizados en el modelo Product. Hice este script de python para descargar el JSon con el formato correcto, luego lo cargué en <https://dummyjson.com/custom-response> import requestsimport json url = "https://api.escuelajs.co/api/v1/products"response = requests.get(url)data = response.json(); filtered\_data = \[] for item in data:    filtered\_item = {        "Id" : item.get("id"),        "Title" : item.get("title"),        "Price": item.get("price"),        "Description": item.get("description"),        "CategoryId" : item\["category"].get("id"),        "Images": item.get("images")    }    filtered\_data.append(filtered\_item) file\_name = "products.json" with open(file\_name, 'w') as json\_file:    json.dump(filtered\_data, json\_file, indent=4) asdd

A mi me sale que no hay productos que mostrar, y en la consola me aparece el siguiente error:

blazor.webassembly.js:1

   crit: Microsoft.AspNetCore.Components.WebAssembly.Rendering.WebAssemblyRenderer[100]
  Unhandled exception rendering component: not found!

System.ApplicationException: not found!
at BlazorApp.ProductService.Get() in C:\Users\dtc4\Documents\Platzi\Blazor\BlazorApp\BlazorApp\Services\ProductService.cs:line 24
at BlazorApp.Pages.Products.GetProducts() in C:\Users\dtc4\Documents\Platzi\Blazor\BlazorApp\BlazorApp\Pages\Products.razor:line 40
at BlazorApp.Pages.Products.OnInitializedAsync() in C:\Users\dtc4\Documents\Platzi\Blazor\BlazorApp\BlazorApp\Pages\Products.razor:line 35
at Microsoft.AspNetCore.Components.ComponentBase.RunInitAndSetParametersAsync()
at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle, ComponentState owningComponentState)

Hice de esta forma para generar el efecto de loading usando el spinner de boostrap:

@if (products?.Count > 0)
{
    <div class="products-container">
        @foreach (var product in products)
        {
              <div class="card">
                <img class="card-img-top" src="@product.Images[0]" alt="Product" loading="lazy" width = "270" height="210">
                <div class="card-body">
                    <h4><b>@product.Title</b></h4>
                    <p>@product.Price?.ToString("C")</p>
                </div> 
            </div>
        }
    </div>
}else 
{
    <div class="d-flex justify-content-center">
        <div class="spinner-border" role="status">
            <span class="visually-hidden">Loading...</span>
        </div>
    </div>
}
Pude solucionar lo del API, pero me muestra estos errores ![](https://static.platzi.com/media/user_upload/image-1810be0c-15c4-473e-a522-a52126bbb5c2.jpg)![]()
profe buenos dias, hay problemas con appSettings.json apiurl: "https://api.escuelajs.co/api" tuve q poner toda la ruta para q funcione..En ProductService: var response = await client.GetAsync("https://api.escuelajs.co/api/v1/products");
No hay Productos (Resuelto) Buenas, primero me encontré con el problema que la URL había cambiado <https://api.escuelajs.co/api/v1/products> Después me salió, que no había productos, pensé que no estaba llamando bien a la API, pero le en el ProductService.cs , le agregue el mensaje de consola, para ver que llegaba `public async Task<List<Product>?> Get()` `{` `var response = await client.GetAsync("v1/products");` `var content = await response.Content.ReadAsStringAsync();` `Console.WriteLine("Contenido: ");` `Console.WriteLine(content);` Resulto que si llegaban los datos. Entonces me di cuenta, que cuando quería des serializar el JSON, se producía el error, después de varios intentos, encontré que el error estaba, en la definición del producto, no coincidía con la información que venia de la API, por eso aparecía vació. En Models/Product.cs cambie la definición del producto por lo siguiente y funciono de maravilla. `public class Product` `{` `public int Id { get; set; }` `public string? Title { get; set; }` `public decimal Price { get; set; }` `public string? Description { get; set; }` `public int CategoryId { get; set; }` `public string[]? Images { get; set; }` `public string? Image { get; set; }` `}` Saludos.
var options = new JsonSerializerOptions() { PropertyNameCaseInsensitive = true };
builder.Services.AddScoped<JsonSerializerOptions>(serviceProvider => options);

He realizado la inyeccion de dependencia desde la clase program.cs para llevar la configuracion global de la clase JsonSerializerOptions y solo inyectarlo

Yo tuve un pequeño error que me hizo pasar algunos minutos tratando de corregir, equivoqué el metodo OnInitializedAsync por OnInitialized. Debemos usar el async para que espere la respuesta del api. Sino aparecera como null exception

Creo que la dificultad mas grande se presenta al intentar usar una versión superior de .NET. Tratando de usar la 7 no hallé como solucionar el error, simplemente no funciona, pienso que una de las causas se debe a que usan versiones diferentes de C#. Al final continuare con la versión que comparte el profe en github, luego de un largo día de tratar dar solución al problema.

interface de productService.cs

public interface IProductService
   {
        Task<List<Product>?> Get();
        Task Add(Product product);
        Task Delete(int productId);
    }

Si les llega a fallar o a marcar IProductService…
es por que falta el using que hace referencia a la carpeta Services, ejemplo:

using BlazorAppVisualStudio.Services;

La API a regresa un solo objeto si la respuesta es de un solo registro o un array si hay varios. Este diseño implica tener que validar desde nuestra aplicación esta situación y adecuar el código de acuerdo a la respuesta. Lo ideal seria que la API regresara siempre un Array, asi sea un solo objeto, una lista o ningun objeto. Entonces, mi metodo GetProducts quedo mas o menos asi ```js public async Task<List<Product>> GetProductsAsync() { var response = await _client.GetAsync("v1/products"); var content = await response.Content.ReadAsStringAsync(); if (!response.IsSuccessStatusCode) { throw new ApplicationException(content); } _logger.LogInformation(content.ToString()); try { _logger.LogInformation("Detectar si el JSON es un objeto o un array"); if (content.TrimStart().StartsWith("[")) { _logger.LogInformation("Si es un array, deserializar como lista de productos"); return JsonConvert.DeserializeObject<List<Product>>(content) ?? new List<Product>(); } else { _logger.LogInformation("Si es un objeto, deserializar como un solo producto y colocarlo en una lista"); var singleProduct = JsonConvert.DeserializeObject<Product>(content); return new List<Product> { singleProduct }; } } catch (JsonException ex) { _logger.LogError("Failed to deserialize the content: {Content}. Error: {Error}", content, ex.Message); throw; } } ```public async Task\<List\<Product>> GetProductsAsync()    {        var response = await \_client.GetAsync("v1/products");        var content = await response.Content.ReadAsStringAsync();         if (!response.IsSuccessStatusCode)        {            throw new ApplicationException(content);        }         \_logger.LogInformation(content.ToString());         try        {            \_logger.LogInformation("Detectar si el JSON es un objeto o un array");             if (content.TrimStart().StartsWith("\["))            {                \_logger.LogInformation("Si es un array, deserializar como lista de productos");                return JsonConvert.DeserializeObject\<List\<Product>>(content) ?? new List\<Product>();            }            else            {                \_logger.LogInformation("Si es un objeto, deserializar como un solo producto y colocarlo en una lista");                var singleProduct = JsonConvert.DeserializeObject\<Product>(content);                return new List\<Product> { singleProduct };            }        }        catch (JsonException ex)        {            \_logger.LogError("Failed to deserialize the content: {Content}. Error: {Error}", content, ex.Message);            throw;        }    }