Specified Cast is not valid using ObservableCollection

iooovoltsiooovolts ✭✭Member ✭✭
edited June 9 in Xamarin.Forms

I have a method which obtains a list of employees from an API and then stores them in an ObservableCollection to be displayed on a ListView. I am having no luck however, as I keep getting this error "System.InvalidCastException: Specified cast is not valid". Any help is much appreciated. I have tried all types of ways to storethe list returned from the API inside the ObservableCollection. I am using MVVM Cross so in this case I use MvxObservableCollection which also works in the exact same way. When I remove the assignment my app doesn't crash so I know 100% something is going wrong there. Please my code below:

public class EmployeeListViewModel : BaseViewModel
    {
        private IMvxNavigationService _navigationService { get; set; }
        private IUserService _userService { get; set; }
        public EmployeeListViewModel(IUserService userAdminService, IMvxNavigationService navigation)
        {
            _navigationService = navigation;
            _userService = userAdminService;
            GetEmployees();
        }

        private async void GetEmployees()
        {
            var employees = await _userService.GetEmployees();
            Employees = new MvxObservableCollection<User>(employees);
        }

        private MvxObservableCollection<User> _employees;
        public MvxObservableCollection<User> Employees
        {
            get => _employees;
            set { SetProperty(ref _employees, value); }
        }
    }

Answers

  • amirvenusamirvenus ✭✭✭ USMember ✭✭✭
    Change private async void GetEmployees to private async Task GetEmployees

    Also you need to await the GetEmployees or use .Wait() when calling it synchronously
  • amirvenusamirvenus ✭✭✭ USMember ✭✭✭
    Also, change get => _employees to:

    get => _employees ?? (_employees == new MvxObservableCollection<User>());
  • iooovoltsiooovolts ✭✭ Member ✭✭

    Thanks, but unfortunately that does not work. I already tried using .Wait(), what ends up happening is that the call to the API never returns, timesout and crashes because the .GetStringAsync("api url") doesn't return. I also in past test instantiated _employees to a new list. I did try what you said again just to be sure. Any other suggestions please?

  • iooovoltsiooovolts ✭✭ Member ✭✭
    edited June 10

    Hi, quick update. I just removed the list instantiation code as a while and I still get the error. Can you please have a look at the API call and see if you can spot a dumb error or something like that?

    public async Task<List<User>> GetEmployees()
        {
        string url = $"{IpAddress}/{_controllerRoute}/getemployees";
        var content = await _httpClient.GetStringAsync(url);
        return JsonConvert.DeserializeObject<List<User>>(content);
        }
    
  • JohnHardmanJohnHardman mod GBUniversity mod

    @iooovolts

    @amirvenus is correct to highlight your use of async/await. From the small amount of code provided, we cannot say definitely that it will cause a problem, but it may do, and if you make a habit of using async void and calling async methods from constructors, you may well run into problems.

    You haven't said which line of code results in the InvalidCastException, so we don't have enough information to definitely give an answer to your question. However, it seems likely that await _userService.GetEmployees(); provides a List<User> but you are attempting to assign that to a MvxObservableCollection<User> and so the exception is thrown. As I said, there isn't enough information provided to be definitive, so if it's not that, I would want to see what the debugger says is in content and what JsonConvert.DeserializeObject<List<User>>(content) converts it to.

  • iooovoltsiooovolts ✭✭ Member ✭✭
    edited June 10

    Hi John, I wasn't able to provide adequate information because Visual Studio, couldn't either. It was trial and error that got me to even figure out why it wasn't working. The API return the data, the property was being populated so I wondered why. Turns out it was something as silly as me putting

Sign In or Register to comment.