My App does not load list of items

Asked

Viewed 100 times

1

I have a App Xamarin.Formsthat consumes two services rest. The first service, consumes normally. However, the second, that I need to pass a parameter, this is not being consumed. I’ve tried several ways and it doesn’t work. I know my code is bugged, but I don’t know where, I don’t know how to consume the service. The variable _data that will fill the Grid with the information, is not come filled and yes null. Below my codes: My data service that should load the URL entries:

public async Task<List<ItensLib>> GetItensLibAsync(int idorcamento)
        {
            try
            {
                string url = "http://www.inetglobal.com.br/autorizador/api/itens/{idorcamento}";
                var response = await client.GetStringAsync(url);
                var itenslib = JsonConvert.DeserializeObject<List<ItensLib>>(response);
                return itenslib.ToList();
            }
            catch (Exception ex)
            {
                throw new Exception(ex.Message);
            }
        } 

My call on the constructor of the xaml.Cs class of my App

public MainPageItens(int idorcamento)
        {
            InitializeComponent();
            this.IdOrcamento = idorcamento;

            CarregaDados(idorcamento);
....

async void CarregaDados(int idorcamento)
        {
            _data = await dataService.GetItensLibAsync(idorcamento);
        }

My complete builder, with the assembly of the Grid

public MainPageItens(int idorcamento)
        {
            InitializeComponent();
            this.IdOrcamento = idorcamento;

            CarregaDados(idorcamento);

            // Crete a grid for "title"
            Grid grid = CreateGrid();
            grid.Children.Add(new Label { Text = "Produto", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 0, 1, 0, 1);
            grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
            grid.Children.Add(new Label { Text = "Qtde", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 2, 3, 0, 1);
            grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
            grid.Children.Add(new Label { Text = "Unitário", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 4, 5, 0, 1);
            grid.Children.Add(SeparatorV(), 5, 6, 0, 1);
            grid.Children.Add(new Label { Text = "Custo", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 6, 7, 0, 1);
            grid.Children.Add(SeparatorV(), 7, 8, 0, 1);
            grid.Children.Add(new Label { Text = "Custo Dia", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 8, 9, 0, 1);
            grid.Children.Add(SeparatorV(), 9, 10, 0, 1);
            grid.Children.Add(new Label { Text = "Ult. Vencto", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 10, 11, 0, 1);
            grid.Children.Add(SeparatorV(), 11, 12, 0, 1);
            grid.Children.Add(new Label { Text = "Total", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 12, 13, 0, 1);
            grid.Children.Add(SeparatorV(), 13, 14, 0, 1);

            grid.Children.Add(SeparatorH(), 0, 14, 1, 2);

            // Create the ListView to visualize my data
            ListView lv = new ListView() { HasUnevenRows = true, SeparatorVisibility = SeparatorVisibility.None };
            lv.ItemsSource = _data;
            lv.ItemTemplate = new DataTemplate(typeof(ListViewTemplateGrid));

            StackLayout sl = new StackLayout() { Children = { grid, lv }, Spacing = 0 };

            this.Content = sl;
        }

This is the statement of the _date Property at the beginning of the class:

List<ItensLib> _data { get; set; }
List<ItensLib> _itens ;
DataService dataService;

Here is the screenshot of the error(says nothing), as I know that _data is null, I think that’s the problem: inserir a descrição da imagem aqui

EDIT1 I overwrote the Onappering method and removed the Constructor’s call and construction of the Grid and switched to this method. And in the Charged Method, I passed him to async Task CarregaDados(int idorcamento);. What passes is the call in the Onappering of this method is giving this error:

Wait operator can only be used in an asynchronous method.

Look how it turned out:

protected override void OnAppearing()
        {
            base.OnAppearing();

            await CarregaDados(IdOrcamento);**Aqui dá erro**

            // Crete a grid for "title"
            Grid grid = CreateGrid();
            grid.Children.Add(new Label { Text = "Produto", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 0, 1, 0, 1);
            grid.Children.Add(SeparatorV(), 1, 2, 0, 1);
            grid.Children.Add(new Label { Text = "Qtde", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 2, 3, 0, 1);
            grid.Children.Add(SeparatorV(), 3, 4, 0, 1);
            grid.Children.Add(new Label { Text = "Unitário", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 4, 5, 0, 1);
            grid.Children.Add(SeparatorV(), 5, 6, 0, 1);
            grid.Children.Add(new Label { Text = "Custo", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 6, 7, 0, 1);
            grid.Children.Add(SeparatorV(), 7, 8, 0, 1);
            grid.Children.Add(new Label { Text = "Custo Dia", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 8, 9, 0, 1);
            grid.Children.Add(SeparatorV(), 9, 10, 0, 1);
            grid.Children.Add(new Label { Text = "Ult. Vencto", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 10, 11, 0, 1);
            grid.Children.Add(SeparatorV(), 11, 12, 0, 1);
            grid.Children.Add(new Label { Text = "Total", TextColor = Color.Red, VerticalOptions = LayoutOptions.Center, HorizontalOptions = LayoutOptions.Center }, 12, 13, 0, 1);
            grid.Children.Add(SeparatorV(), 13, 14, 0, 1);

            grid.Children.Add(SeparatorH(), 0, 14, 1, 2);

            // Create the ListView to visualize my data
            ListView lv = new ListView() { HasUnevenRows = true, SeparatorVisibility = SeparatorVisibility.None };
            lv.ItemsSource = _data;
            lv.ItemTemplate = new DataTemplate(typeof(ListViewTemplateGrid));

            StackLayout sl = new StackLayout() { Children = { grid, lv }, Spacing = 0 };

            this.Content = sl;
        }

And the method Loaded:

async Task CarregaDados(int idorcamento)
        {
            _data = await dataService.GetItensLibAsync(idorcamento);
        }
  • Just one question: loadDados is an async method, but it is being called from within a constructor. Does this not contribute to the problem? For builders do not accept at least declaration of anything async, so I understand. If it is this, how do I build my Grid the moment the class is instantiated ?

  • I’ll restart the VS or the PC

  • Which platform are you running the app, android, Ios or WP? Because the answer essentially depends on this information.

  • @Grupocdsinformática, I use Xamarin.Forms(Cross Platform), but I can only test on Android

2 answers

2

As the reply of the comment follows possible solution:

On android check the following:

  1. You must have internet permission in the manifest;

  2. Every internet call has to be made in an Asynctask or any other background task. In your case, by code, it’s being done directly on the screen. Then I recommend creating an Asynctask (not the Xamarin task, but the Asynctask class from android) and then making the call inside it. Follow an example of class.

public class BgTask : AsyncTask<String, Java.Lang.Void, String> { /// <summary> /// Método que vai fazer a chamada em background /// </summary> protected override String RunInBackground(params string[] @params) { } /// <summary> /// Executado depois que o RunInBackground terminar, geralmente usado para retornar o resultado. /// </summary> protected override void OnPostExecute(string result) { } }

The call for this task

new BgTask().execute("param");
  • I did this: I overscrutinized the Onappearing() method and passed everything from my builder to that method. But the whole problem was on that line, an elementary mistake that couldn’t have happened: I did: DataService dataService and should be DataService dataService = new DataService()

2

The problem is when your code gets here:

lv.ItemsSource = _data;

...the method CarregaDados(idorcamento) which has been called some lines above has not yet executed, nor populated the variable _data. You need to wait for this method to finish its execution, for example:

Task.Run(async () => await CarregaDados(idorcamento)).GetAwaiter().GetResult();

This is one way to execute synchronously an asynchronous method, which is the case of CarregaDados.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.