How can I limit the rows to one in database? - xamarin

I have a table named profit model:
I would like to active different profitmodel, and the data in table will be updated.
Now I am using UpdateAsync, but it doesn't work... How can I achieve this?
async void Active_Clicked(object sender, System.EventArgs e)
{
var profitmodel = (sender as Button).CommandParameter as ProfitModel;
await conn.CreateTableAsync<ProfitModelInUsed>();
//System.Diagnostics.Debug.WriteLine(product.ProductName);
var profitmodelInUsed = new ProfitModelInUsed
{
ProfitModel_ID = profitmodel.ProfitModel_ID,
ProfitModel_Name = profitmodel.ProfitModel_Name,
ExchangeRate = profitmodel.ExchangeRate,
Profit = profitmodel.Profit
};
await conn.UpdateAsync(profitmodelInUsed);
await DisplayAlert("This ProfitModel is Applied", profitmodelInUsed.ProfitModel_Name, "OK");
}
And I don't want to have more than one rows in this table.

Apply a PrimaryKey to your ProfitModel_ID property within your ProfitModelInUsed model:
public class ProfitModelInUsed
{
[PrimaryKey]
public string ProfitModel_ID { get; set; }
// ~~~ other properties
}
And set the ProfitModel_ID property using a const:
profitmodelInUsed.ProfitModel_ID = "InUseProfitModel"
await conn.UpdateAsync(profitmodelInUsed);
Retrive it via:
var profitmodelinuse = conn.FindAsync<ProfitModelInUsed>("InUseProfitModel");

Related

Initialize an xamarin view after an async method

Good evening everyone.
For some time now I have been to Xamarin. My first tests are rather conclusive. I decided to try to make a small application that retrieves information in a database via an API and then update this data via a ListView.
When I launch the application on my emulator everything works but as soon as I install the application on my phone it crashes. I thought this was because the API but I have an API that I use to check the Login / password that works correctly.
The API that returns the data reviews a lot of line about 3500/4000, can this be the reason?
So I passed the loading of the data in my viewModel in an async method but the problem now is that the view loads before the data is loaded correctly. Is there a way to get the view initialized after the data is loaded?
Below my code.
Initializing my viewModel
class ManageInventViewModel
{
public ObservableCollection<InventViewModel> InventProduct { get; set; }
public Command<InventViewModel> UpdateCommand
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = invent.IndexLigneInventaire;
InventProduct.Remove(invent);
InventProduct.Insert(index, invent);
});
}
}
public Command<InventViewModel> ResetStock
{
get
{
return new Command<InventViewModel>(invent =>
{
var index = InventProduct.IndexOf(invent);
InventProduct.Remove(invent);
invent.RealStockProduct = 0;
InventProduct.Insert(index, invent);
});
}
}
public ManageInventViewModel()
{
LoadInventaire();
}
private async void LoadInventaire()
{
var listMvt = await Utils.Utils.GetListMouvementUntilDate();
var listStock = Utils.Utils.GetStockByProduct(listMvt).Take(20);
InventProduct = new ObservableCollection<InventViewModel>();
var indexLine = 0;
foreach (var stock in listStock)
{
var inventViewModel = new InventViewModel
{
LibelleProduit = stock.LibelleProduit,
PrCodeProduit = stock.PrCodeProduit,
UpCodeProduit = stock.UpCodeProduit,
RealStockProduct = stock.StockTheoProdct,
StockTheoProdct = stock.StockTheoProdct,
IndexLigneInventaire = indexLine
};
++indexLine;
InventProduct.Add(inventViewModel);
}
}
}
Initializinz my view
public partial class InventPage : ContentPage
{
public InventPage()
{
InitializeComponent();
TableInvent.ItemSelected += (sender, e) =>
{
if (TableInvent.SelectedItem != null)
{
if (TableInvent.SelectedItem is InventViewModel item)
{
PopupNavigation.Instance.PushAsync(new ChangeStockModal(item, this));
}
TableInvent.SelectedItem = null;
}
};
}
private void Reset_Stock(object sender, EventArgs e)
{
var input = sender as Button;
var inventViewModel = input?.BindingContext as InventViewModel;
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.ResetStock.Execute(inventViewModel);
}
public void Update_Stock_List(InventViewModel dataStockUpdate)
{
var listViewModel = BindingContext as ManageInventViewModel;
listViewModel?.UpdateCommand.Execute(dataStockUpdate);
PopupNavigation.Instance.PopAsync();
}
}
Thanks
I managed to create the ActivityIndicator but I can not get my data loaded while I'm displaying the wait screen.
Regarding this issue, I don't see you useActivityIndicator from your code,maybe you didn't update your code, I think if you use useActivityIndicator , You can bind one property to ActivityIndicator IsRunning and IsVisible, then you can solve your issue.
Related use ActivityIndicator step, you can take a look:
ActivityIndicator

Consuming WEB API Xamarin Forms

I have a WEB API hosted on a server, there I have a Products table with Name and Description.I already checked for the postman and this is ok, when I try to implement the method in xamarin by visual studio to bring a record by its name and display in a listview I receiving the following message
Can not implicitly convert type "void"in
"System.Collections.Generic.List"
public async void GetProductByName(string Name)
{
var client = new HttpClient(handler);
client.Timeout = TimeSpan.FromSeconds(120);
txtTest.Text =
"http://www.ProdutosAPITest6.hostname.com/api/products";
var URI = txtTest.Text + "/" + Name.ToString();
var requestMessage = new HttpRequestMessage
{
Method = HttpMethod.Get,
RequestUri = new Uri(URI)
};
var response = await client.SendAsync(requestMessage);
if (response.IsSuccessStatusCode == true)
{
var products = await response.Content.ReadAsStringAsync();
var resultModel = JsonConvert.DeserializeObject<Product>
(products);
return resultModel;
}
}
MY CLASS
namespace XF_ConsumingWebAPI.Models
{
public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
}
MY LISTVIEW
public ListView myListView { get { return ProductsList; }}
protected override async void OnAppearing()
{
var name = //pass name;
List<ProductModel> products = await GetProductByName(Name);
if (products.Count() > 0)
{
myListView.ItemsSource = products;
}
base.OnAppearing();
}
in the line List<Produto> products = await LoadData(Name);
I'm receiving the following message
Can not implicitly convert type "void" in
"System.Collections.Generic.List<XF_ConsumingWebAPI.Models.Product>"
Try to set ItemSource in GetproductByName function instead of returning resultModel i.e.
myListView.ItemSource=resultModel

How to store credentials with Xamarin.Auth in a list and keep adding value onto it?

I am storing some cardcredentials and i look to display the last 4 digits in a list but i am not sure how i can keep adding data.
With my current code it doesnt keep adding onto the list, instead it replaces the old one.
async void AddCard (object s, Eventargs e)
{
Account account = new Account();
account.Username = "Credentials";
account.Properties.Add("LastFour", LastFourString);
account.Properties.Add("CardBrand", BrandString);
account.Properties.Add("CardToken", TokenString);
AccountStore.Create().Save(account, "Credentials");
AddNewCard();
}
public class Info
{
public string LastFour { get; set; }
public string CardBrand { get; set; }
public string CardToken { get; set; }
}
async void AddNewCard()
{
var Account = AccountStore.Create().FindAccountsForService("Credentials");
var InfoList = new List<Info>();
foreach (var Data in Account)
{
InfoList.Add(new Info()
{
LastFour = "**********" + Data.Properties["LastFour"],
CardBrand = Data.Properties["CardBrand"]
CardToken = Data.Properties["CardToken"]
});
}
CardListView.ItemsSource = InfoList;
}
First of all, avoid async void if possible. For example, it seems that AddCard method is an event handler for a button, so its signature is fixed, but you can use async Task for add new card method.
For your requirement, you can use https://learn.microsoft.com/en-us/xamarin/essentials/secure-storage easily.

How can I find out the value of an Id from a Tapped view cell event

I have code to call an event when a ViewCell is tapped. In the event handler I need to know the Id value from the cell that called the event. can someone help suggest how I can get this value.
Also I would like to pass this value to the categoriesPage that is being opened. How can I do this?
public class CategoryGroupWordCountVM
{
bool isToggled;
public int Id { get; set; }
public string Name { get; set; }
public bool IsToggled { get; set; }
public int TotalWordCount { get; set; }
}
List<CategoryGroupWordCountVM> categoryGroups;
foreach (var category in categoryGroups) {
var cell = new CategoryGroupTextCell { BindingContext = category };
cell.Tapped += openCategoriesPage;
section.Add(cell);
}
async void openCategoriesPage(object sender, EventArgs e)
{
var ctg = (CategoryGroupTextCell)sender;
var Id = ??
await Navigation.PushAsync(categoriesPage);
}
You can use BindingContext
For example: (assuming CategoryPageVM is viewmodel-type for the page you are navigating to on tapped event).
async void openCategoriesPage(object sender, EventArgs e)
{
var ctg = (CategoryGroupTextCell)sender;
// get id from binding-context
var id = (ctg.BindingContext as CategoryGroupWordCountVM)?.Id;
// construct or get viewmodel for the page you are navigating to
var newPageVM = new CategoryPageVM { CategoryId = id };
// assign viewmodel to page
var categoriesPage = new CategoryPage { BindingContext = newPageVM };
await Navigation.PushAsync(categoriesPage);
}
Also, this link offers more details regarding passing data during navigation.

Query parse.com data based on pointer user field

I'm having some issue querying parse.com data. Here is my current code.
I have a 'Classifieds' parse "table" which contains several fields. One of those is 'user' of type Pointer<_User> and contains the userid of the user who created an ad.
In my query, I wish to get all classifieds for a specific user. 'userid' of that user equals to 'og8wGxHKOm'.
The query always returns null. Though, there is at least one ad (record) for that specific user as shown on the screen capture.
What am I missing ? - Working with latest Parse .Net SDK
namespace FindAllAds
{
public partial class _Default : Page
{
protected async void Page_Load(object sender, EventArgs e)
{
string x = await MyAds();
parselabel.Text = x;
}
private async Task<string> MyAds()
{
var query = ParseObject.GetQuery("Classifieds")
.WhereEqualTo("user", ParseObject.CreateWithoutData("User", "og8wGxHKOm"));
IEnumerable<ParseObject> results = await query.FindAsync();
//for testing only
string myString = "";
foreach (var value in results)
{
myString += value["title"] + "<br/>";
}
return myString;
}
}
}
screen capture
The name of the user class is "_User", so:
var userPointer = ParseObject.CreateWithoutData("_User", "og8wGxHKOm");
var query = ParseObject.GetQuery("Classifieds").WhereEqualTo("user", userPointer);

Resources