DotVVM - GridViewDataSet not loading any data - c#

I am stuck on problem where my facade method is never called so my returned items are always zero. I dont exactly know why this happens since it should at least load items on initial page load. Also I got almost identical ViewModel where it works fine.
Here is my viewmodel where I want to load FavouriteCommodities into GridViewDataSet
//initialized via constructor
private readonly FavouriteCommodityFacade _favouriteCommodityFacade;
public GridViewDataSet<FavouriteCommodityDTO> GridViewDataSetItems { get; set; }
public int PageSize { get; set; } = 10;
private ISortingOptions DefaultSortOptions => new SortingOptions();
public override Task Init()
{
GridViewDataSetItems = new GridViewDataSet<FavouriteCommodityDTO>()
{
PagingOptions = { PageSize = PageSize },
SortingOptions = DefaultSortOptions
};
return base.Init();
}
public override Task PreRender()
{
if (!Context.IsPostBack || GridViewDataSetItems.IsRefreshRequired)
{
LoadData();
}
return base.PreRender();
}
public void LoadData()
{
FavouriteCommodityGroups = _userAccountFavouriteProductsFacade.GetAllFavouriteProductsToUser();
//this never fires my facade method below
GridViewDataSetItems.OnLoadingData = option => _favouriteCommodityFacade.GetAssignedFavouriteProductsToGroup(option);
}
Here is my method in my facade which is never fired.
public GridViewDataSetLoadedData<FavouriteCommodityDTO>
GetAssignedFavouriteProductsToGroup (IGridViewDataSetLoadOptions gridViewDataSetLoadOption)
{
using (unitOfWorkProvider.Create())
{
var query = _favouriteCommodityByChosenGroupQuery();
FavouriteProductByGroupFilter.FavouriteGroupId = 16;
query.Filter = FavouriteProductByGroupFilter;
var x = GetGridViewDataSetLoadedData(gridViewDataSetLoadOption, query);
return x.Result;
}
}
I am also wondering if there is possibility to load those items on user click event. When I looked into namespace DotVVM.Framework.Controls I didnt find anything useful for that.

So I figure out after a while that Repeater component not triggering method. I had to use only GridView component in view.

Related

App crashes on iOS with no internet connection

I am using async method to retrieve JSON data , the data comes successfully but when I turn off the internet in my device, the App stops unfortunately. How can I handle this exception, or how can I handle internet Connectivity in Xamarin.Forms.
public partial class MainActivity : ContentPage
{
public ObservableCollection<Adverts> Zoos { get; set; }
public int Count = 0;
public short Counter = 0;
public int SlidePosition = 0;
string heightList;
int heightRowsList = 90;
private const string Url = "http://eamobiledirectory.com/cooperp/Mobile/Mobileapi.aspx?Action=Featured&Country=Uganda";
private const string BaseImageUrl = "http://eamobiledirectory.com/cooperp/Images/app_images/";
private HttpClient _client = new HttpClient();
public ObservableCollection<Adverts> adverts;
public MainActivity()
{
InitializeComponent();
TrendingShows();
if (CrossConnectivity.Current.IsConnected)
{
OnAppearing();
}
else
{
App.Current.MainPage.DisplayAlert("Alert ", "No internet Connection Please", "OK");
}
}
protected override async void OnAppearing()
{
var content = await _client.GetStringAsync(Url);
var adv = JsonConvert.DeserializeObject<List<Adverts>>(content);
adverts = new ObservableCollection<Adverts>(adv);
AdvertsCarousel.ItemsSource = adverts;
// attaching auto sliding on to carouselView
Device.StartTimer(TimeSpan.FromSeconds(18), () =>
{
SlidePosition++;
if (SlidePosition == adverts.Count)
SlidePosition = 0;
AdvertsCarousel.Position = SlidePosition;
return true;
});
}
i tried this but it seems not working , How can i handle this.
Either use a simple try/catch construction, this also helps for any other errors that might occur. Or look into the Connectivity Plugin. This has some methods, properties and events to determine what the state of your connection is and you can handle your content accordingly.
Edit
As a follow up to your edited question; you do not need to call OnAppearing yourself. Either abstract your code to some kind of method that refreshes the data if you need to, or find another method that is better suitable.
You should also move your check closer to the point where you are fetching your data. For instance, do it more like this:
protected override async void OnAppearing()
{
adverts = new List<Adverts>();
if (CrossConnectivity.Current.IsConnected)
{
var content = await _client.GetStringAsync(Url);
var adv = JsonConvert.DeserializeObject<List<Adverts>>(content);
adverts = new ObservableCollection<Adverts>(adv);
}
else
{
// TODO: Either show cached adverts here, or hide your carrousel or whatever you want to do when there is no connection
}
AdvertsCarousel.ItemsSource = adverts;
// attaching auto sliding on to carouselView
Device.StartTimer(TimeSpan.FromSeconds(18), () =>
{
SlidePosition++;
if (SlidePosition == adverts.Count)
SlidePosition = 0;
AdvertsCarousel.Position = SlidePosition;
return true;
});
}

Object is not set in ViewModel class and control is directly move from data access class to View

I want to fetch first record from AboutUs table and display as a content label.
I have created 4 classes in MVVM pattern.
First is Model class AboutUs.cs
[Table("tblAboutUs")]
public class AboutUs
{
[PrimaryKey, AutoIncrement, NotNull]
public int IDP { get; set; }
public string Content { get; set; }
}
Second is Data Access class
SQLiteAboutUs.cs
public class SQLiteAboutUs
{
private static readonly AsyncLock Mutex = new AsyncLock();
private SQLiteAsyncConnection dbConn;
public int StatusCode { get; set; }
public SQLiteAboutUs(ISQLitePlatform sqlitePlatform, string dbPath)
{
if (dbConn == null)
{
var connectionFunc = new Func<SQLiteConnectionWithLock>(() =>
new SQLiteConnectionWithLock
(
sqlitePlatform,
new SQLiteConnectionString(dbPath, storeDateTimeAsTicks: false)
));
dbConn = new SQLiteAsyncConnection(connectionFunc);
dbConn.CreateTableAsync<Model.AboutUs>();
}
}
public SQLiteAboutUs()
{
}
public async Task Save(Model.AboutUs content)
{
using (await Mutex.LockAsync().ConfigureAwait(false))
{
StatusCode = 0;
await dbConn.InsertAsync(new Model.AboutUs { Content = content.Content });
StatusCode = 1;
}
//For Get first Row from Table
public async Task<Model.AboutUs> GetAllData()
{
return await dbConn.Table<Model.AboutUs>().Where(x => x.IDP == 1).FirstOrDefaultAsync();
}
}
Third class ViewModel Class
AboutUsViewModel.cs
public class AboutUsViewModel
{
readonly SQLiteAboutUs _db;
public string AboutUsContent { get; set; }
//public string AboutUs;
public AboutUsViewModel()
{
_db = new SQLiteAboutUs();
}
public async void FirstRecord()
{
Model.AboutUs obj = await _db.GetAllData();
this.AboutUsContent = obj.Content;
}
}
Forth one is Code behind file of my xaml pages.
AboutUs.xaml.cs
public partial class AboutUs : ContentPage
{
readonly AboutUsViewModel aboutUsViewModel;
public AboutUs()
{
InitializeComponent();
aboutUsViewModel = new AboutUsViewModel();
aboutUsViewModel.FirstRecord();
lblContent.Text = aboutUsViewModel.AboutUsContent;
}
}
I have debug code but problem is In AboutUsViewModel.cs class in FirstRecord Method object can not be set that's why AboutUsContent string property is also not set.
I can't figure out why my debugger directly jump from GetAllData() method in SQLiteAboutUs.cs to label.text in code behind file of view?
Welcome in the wonderfull world of asynchronicity. I encourage you to read carefully about how await is working: How and When to use `async` and `await`
It is not a blocking call. Thus you create the view AboutUs. It creates the ViewModel AboutUsViewModel. It calls
aboutUsViewModel.FirstRecord();
But does not wait for the call to be complete (dont't forget you marked your FirstRecord function as async...)
So it calls
Model.AboutUs obj = await _db.GetAllData();
And directly return to the caller because of the await operator.
That's why it directly jump to
lblContent.Text = aboutUsViewModel.AboutUsContent;
What you would like is Something like
await aboutUsViewModel.FirstRecord();
To wait the call to be complete before going to the next line. But of course you can't do that, because you are in a constructor and you can't have an async constructor. And calling a database (or actually anything that could likely failed) in a constructor is a bad practice anyway.
I would advise you to let only InitializeComponent() in the constructor, and then use Something like the OnDataLoaded() event of your view to perform your async call with a await.
Hope it helps.

Nancy: Modify model in AfterRequest event?

I want to add an AfterRequest event handler to my Bootstrapper.cs that is able to modify the model on the Response after every route is invoked. Is this possible? I don't see any properties on the Response where I could gain access to the Model (if there is one).
Here is my example usage (from Bootstrapper.cs):
protected override void ApplicationStartup(..., IPipelines pipelines)
{
...
pipelines.AfterRequest += ModifyModel;
}
private void ModifyModel(NancyContext ctx)
{
// do things to the response model here
}
If you're still need this functionality you may be interested in an extension I just published on Nuget: https://www.nuget.org/packages/Nancy.ModelPostprocess.Fody. We needed a similar functionality in our project
This will allow you to modify your models after the route has already executed. Do have a look at the description on the Bitbucket page
Please tell me if this suits your needs.
I think is not that simple, you should inspect the ctx.Response.Content in order to know which deserializer is used and what object are you returning, I made a simple example returning a Foo Object Serialized as Json.....
public class MyBootstrapper : Nancy.DefaultNancyBootstrapper
{
protected override void ApplicationStartup(TinyIoC.TinyIoCContainer container, Nancy.Bootstrapper.IPipelines pipelines)
{
base.ApplicationStartup(container, pipelines);
pipelines.AfterRequest += ModifyModel;
}
private void ModifyModel(NancyContext ctx)
{
Foo foo;
using(var memory = new MemoryStream())
{
ctx.Response.Contents.Invoke(memory);
var str = Encoding.UTF8.GetString(memory.ToArray());
foo = JsonConvert.DeserializeObject<Foo>(str);
}
ctx.Response.Contents = stream =>
{
using (var writer = new StreamWriter(stream))
{
foo.Code = 999;
writer.Write(JsonConvert.SerializeObject(foo));
}
};
}
}
public class HomeModule : Nancy.NancyModule
{
public HomeModule()
{
Get["/"] = parameters => {
return Response.AsJson<Foo>(new Foo { Bar = "Bar" });
};
}
}
public class Foo
{
public string Bar { get; set; }
public int Code { get; set; }
}
After researching this more, this is simply not possible (at least within reason) to do with the Nancy framework as it exists today.

Error Reporting

I have a class that follows the Command Pattern.
It has 2 methods which are Execute, and CanExecute which checks whether to invoke Execute or not (they derive from ICommand).
CanExecute invokes a few methods that check that all required services are running, the version is correct, etc.
After CanExecute is invoked, it may fail and return false and I need to know why. Is it because of a bad version, services, missing file, etc.
What is the best strategy to know what is the problem
One option is whenever a required condition fails I can throw an exception that will describe the error in the message field. However the possibility that it will fail is expected and you shouldn't use exceptions for regular flow of control. So I'm really not sure.
Thank you.
You can use a collection of "reasons" that will tell the users of the class why CanExecute returned false. The reasons can be a simple IEnumerable<string>.
public bool CanExecute() {
var messages = new List<string>();
if (!Condition1) {
messages.Add("Missing Condition1");
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<string> Messages { get; private set; }
Then, client code can show the collection of messages to end-users.
UPDATE:
You can also associate new commands with the messages to give the users ways to fix the problems found. In this case, instead of an IEnumerable<string>, you can create your own class that encapsulates that information:
public class Message {
public string Text { get; set; }
public ICommand Command { get; set; }
}
...
public bool CanExecute() {
var messages = new List<Message>();
if (!Condition1) {
messages.Add(
new Message {
Text = "Missing Condition1",
Command = new FixCondition1Command()
}
);
}
...
Messages = messages;
return messages.Count == 0;
}
public IEnumerable<Message> Messages { get; private set; }
UPDATE: Reworked based on feedback.
Since the UI needs the reasons CanExecute() returns false, two things come to mind:
Option 1: Add an enumerable message property to the command interface and populate it as needed during the call to CanExecute(). The UI could then interrogate the property as needed. If you go this route, make sure you clear out the contents of the property each call to CanExecute() so you don't lose track of state.
public interface ICommand
{
IEnumerable<string> Messages { get; }
bool CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public IEnumerable<string> Messages { get; private set; }
public bool CanExecute()
{
var messages = new List<string>();
var canExecute = true;
if (SomeCondition)
{
canExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
canExecute = false;
messages.Add("Another reason");
}
Messages = messages;
return canExecute;
}
public void Execute() { }
}
Option 2: Have CanExecute() return an object which contains the bool as well as an enumerable messages property. This makes it obvious that the messages only apply to that call of CanExecute(). However, depending on where/how you're implementing (e.g. data binding), this could complicate other scenarios more than you're looking for.
public class CanExecuteResult
{
public bool CanExecute { get; set; }
public IEnumerable<string> Messages { get; set; }
}
public interface ICommand
{
CanExecuteResult CanExecute();
void Execute();
}
public class SomeCommand : ICommand
{
public CanExecuteResult CanExecute()
{
var result = new CanExecuteResult { CanExecute = true };
var messages = new List<string>();
if (SomeCondition)
{
result.CanExecute = false;
messages.Add("Some reason");
}
if (AnotherCondition)
{
result.CanExecute = false;
messages.Add("Another reason");
}
result.Messages = messages;
return result;
}
public void Execute() { }
}
Obviously, the specifics of how you want to handle the interfaces, enumerable types, etc. is up to you. The code is just a representation of the idea.
Bool CanExecute()
{
if(!CheckXXX)
throw new Exception("CheckXXX function throws an exception")
if(!CheckYYY)
throw new Exception("CheckYYY function throws an exception")
if(!CheckZZZ)
throw new Exception("CheckZZZ function throws an exception")
return true; //everything is working fine
}

Trying to shy away from a singleton/god/manager class. Not sure how I am supposed to sustain functionality, though

I have a class which has been steadily growing over time. It's called LayoutManager.
It started as a way for me to keep track of which dynamically created controls were on my page. So, for instance, I have this:
public CormantRadDockZone()
{
ID = String.Format("RadDockZone_{0}", Guid.NewGuid().ToString().Replace('-', 'a'));
MinHeight = Unit.Percentage(100);
BorderWidth = 0;
HighlightedCssClass = "zoneDropOk";
CssClass = "rightRoundedCorners";
LayoutManager.Instance.RegisteredDockZones.Add(this);
}
In this way, during the beginning stages of the Page Lifecycle, controls would be re-created and they would add themselves to their respective control's list.
A while later I found myself passing the 'Page' object between methods. This was for the sole purpose of being able to access controls found on Page. I thought to myself -- well, I already have a Layout Manager, I'll just treat the static controls in the same way.
As such, my Page_Init method now looks like this mess:
protected void Page_Init(object sender, EventArgs e)
{
SessionRepository.Instance.EnsureAuthorized();
LayoutManager.Instance.RegisteredPanes.Clear();
LayoutManager.Instance.RegisteredDocks.Clear();
LayoutManager.Instance.RegisteredDockZones.Clear();
LayoutManager.Instance.RegisteredSplitters.Clear();
LayoutManager.Instance.RegisteredSplitBars.Clear();
LayoutManager.Instance.RegisteredPageViews.Clear();
LayoutManager.Instance.CheckBox1 = CheckBox1;
LayoutManager.Instance.CheckBox4 = CheckBox4;
LayoutManager.Instance.StartEditButton = StartEditButton;
LayoutManager.Instance.FinishEditButton = FinishEditButton;
LayoutManager.Instance.RadNumericTextBox1 = RadNumericTextBox1;
LayoutManager.Instance.RadNumericTextBox2 = RadNumericTextBox2;
LayoutManager.Instance.LeftPane = LeftPane;
LayoutManager.Instance.DashboardUpdatePanel = DashboardUpdatePanel;
LayoutManager.Instance.CustomReportsContainer = CustomReportsContainer;
LayoutManager.Instance.HistoricalReportsContainer = HistoricalReportsContainer;
RegenerationManager.Instance.RegenerateReportMenu();
LayoutManager.Instance.MultiPage = DashboardMultiPage;
LayoutManager.Instance.MultiPageUpdatePanel = MultiPageUpdatePanel;
LayoutManager.Instance.TabStrip = DashboardTabStrip;
RegenerationManager.Instance.RegenerateTabs(DashboardTabStrip);
RegenerationManager.Instance.RegeneratePageViews();
LayoutManager.Instance.Timer = RefreshAndCycleTimer;
LayoutManager.Instance.Timer.TimerEvent += DashboardTabStrip.DoTimerCycleTick;
RegenerationManager.Instance.RegeneratePageState();
}
I'm looking at that and saying no, no, no. That is all wrong. Yet, there are controls on my page which are very dependent on each other, but do not have access to each other. This is what seems to make this so necessary.
I think a good example of this in practice would be using UpdatePanels. So, for instance, DashboardUpdatePanel is being given to the LayoutManager. There are controls on the page which, conditionally, should cause the entire contents of the dashboard to update.
Now, in my eyes, I believe I have two options:
Inside the object wanting to call UpdatePanel.Update(), I recurse up through parent objects, checking type and ID until I find the appropriate UpdatePanel.
I ask LayoutManager for the UpdatePanel.
Clearly the second one sounds cleaner in this scenario... but I find myself using that same logic in many instances. This has resulted in a manager class which looks like this:
public class LayoutManager
{
private static readonly ILog _logger = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
private static readonly LayoutManager _instance = new LayoutManager();
private LayoutManager() { }
public static LayoutManager Instance
{
get { return _instance; }
}
private IList<CormantRadDock> _registeredDocks;
private IList<CormantRadDockZone> _registeredDockZones;
private IList<CormantRadPane> _registeredPanes;
private IList<CormantRadSplitter> _registeredSplitters;
private IList<CormantRadSplitBar> _registeredSplitBars;
private Dictionary<string, StyledUpdatePanel> _registeredUpdatePanels;
private IList<CormantRadPageView> _registeredPageViews;
public RadMultiPage MultiPage { get; set; }
public CormantTimer Timer { get; set; }
public CormantRadListBox HistoricalReportsContainer { get; set; }
public CormantRadListBox CustomReportsContainer { get; set; }
public StyledUpdatePanel MultiPageUpdatePanel { get; set; }
public CormantRadTabStrip TabStrip { get; set; }
public RadPane LeftPane { get; set; }
public StyledUpdatePanel DashboardUpdatePanel { get; set; }
public RadButton ToggleEditButton { get; set; }
public CheckBox CheckBox1 { get; set; }
public CheckBox CheckBox4 { get; set; }
public RadNumericTextBox RadNumericTextBox1 { get; set; }
public RadNumericTextBox RadNumericTextBox2 { get; set; }
public RadButton StartEditButton { get; set; }
public RadButton FinishEditButton { get; set; }
public IList<CormantRadDock> RegisteredDocks
{
get
{
if (Equals(_registeredDocks, null))
{
_registeredDocks = new List<CormantRadDock>();
}
return _registeredDocks;
}
}
public IList<CormantRadDockZone> RegisteredDockZones
{
get
{
if (Equals(_registeredDockZones, null))
{
_registeredDockZones = new List<CormantRadDockZone>();
}
return _registeredDockZones;
}
}
public IList<CormantRadPane> RegisteredPanes
{
get
{
if (Equals(_registeredPanes, null))
{
_registeredPanes = new List<CormantRadPane>();
}
return _registeredPanes;
}
}
public IList<CormantRadSplitter> RegisteredSplitters
{
get
{
if (Equals(_registeredSplitters, null))
{
_registeredSplitters = new List<CormantRadSplitter>();
}
return _registeredSplitters;
}
}
public IList<CormantRadSplitBar> RegisteredSplitBars
{
get
{
if (Equals(_registeredSplitBars, null))
{
_registeredSplitBars = new List<CormantRadSplitBar>();
}
return _registeredSplitBars;
}
}
public Dictionary<string, StyledUpdatePanel> RegisteredUpdatePanels
{
get
{
if( Equals( _registeredUpdatePanels, null))
{
_registeredUpdatePanels = new Dictionary<string, StyledUpdatePanel>();
}
return _registeredUpdatePanels;
}
}
public IList<CormantRadPageView> RegisteredPageViews
{
get
{
if (Equals(_registeredPageViews, null))
{
_registeredPageViews = new List<CormantRadPageView>();
}
return _registeredPageViews;
}
}
public StyledUpdatePanel GetBaseUpdatePanel()
{
string key = MultiPage.PageViews.Cast<CormantRadPageView>().Where(pageView => pageView.Selected).First().ID;
return RegisteredUpdatePanels[key];
}
public CormantRadDockZone GetDockZoneByID(string dockZoneID)
{
CormantRadDockZone dockZone = RegisteredDockZones.Where(registeredZone => dockZoneID.Contains(registeredZone.ID)).FirstOrDefault();
if (Equals(dockZone, null))
{
_logger.ErrorFormat("Did not find dockZone: {0}", dockZoneID);
}
else
{
_logger.DebugFormat("Found dockZone: {0}", dockZoneID);
}
return dockZone;
}
public CormantRadPane GetPaneByID(string paneID)
{
CormantRadPane pane = RegisteredPanes.Where(registeredZone => paneID.Contains(registeredZone.ID)).FirstOrDefault();
if (Equals(pane, null))
{
_logger.ErrorFormat("Did not find pane: {0}", paneID);
}
else
{
_logger.DebugFormat("Found pane: {0}", paneID);
}
return pane;
}
public CormantRadDock GetDockByID(string dockID)
{
CormantRadDock dock = RegisteredDocks.Where(registeredZone => dockID.Contains(registeredZone.ID)).FirstOrDefault();
if (Equals(dock, null))
{
_logger.ErrorFormat("Did not find dock: {0}", dockID);
}
else
{
_logger.DebugFormat("Found dock: {0}", dockID);
}
return dock;
}
}
Am I on a bad path? What steps are generally taken at this point?
EDIT1: I have decided to start down the path of improvement by finding the controls which are least-integrated into LayoutManager and finding ways of breaking them down into separate objects. So, for instance, instead of assigning the HistoricalReportsContainer and CustomReportsContainer objects to LayoutManager (which is then used in RegenerationManager.RegenerateReportMenu) I have moved the code to RadListBox "Load" event. There, I check the ID of the control which is loading and react accordingly. A strong first improvement, and has removed 2 controls and a method from LayoutManager!
Inversion of control is a general approach that people use for such problems. Your dependencies should not be stored in the one Jack-Bauer-kind-of-style class, but rather be injected, for example via constructor. Take a look at the IoC containers, such as Castle Windsor, Unity, NInject or any other.
I'm not sure how this would interact with future plans of MVC, but had you considered refactoring chunks of LayoutManager into an abstract class that inherits from Page, then having your actual pages inherit from that abstract class?

Categories

Resources