Oxyplot in xamarin not generated - xamarin

I ran in to an issue in generating oxyplot with dynamic data. This is the first time I'm using oxyplot with dynamic data.
public async Task<PlotModel> AreaChart_NoOfPoliciesAsync()
{
var plotModel1 = new PlotModel { Title = "Number of Policies with last year" };
plotModel1.InvalidatePlot(true);
try
{
var s1 = new AreaSeries()
{
Title = "Number of policies in last year",
Color = OxyColors.LightPink,
MarkerType = MarkerType.Circle,
MarkerSize = 6,
MarkerStroke = OxyColors.White,
MarkerFill = OxyColors.LightPink,
MarkerStrokeThickness = 1.5
};
string year_str = DateTime.Today.AddYears(-1).ToString("yyyy");
int running_month = 1;
string running_month_str;
List<MonthlyPerformance> last_year = await _apiServices.GetMonthlyPerformance(Settings.AccessToken, Settings.agentCode, year_str);
last_year = last_year.FindAll(x => x.BUSS_TYPE == "Total");
last_year.Sort((x, y) => x.Y_MONTH.CompareTo(y.Y_MONTH));
s1.Points.Add(new DataPoint(0, 0));
foreach (MonthlyPerformance item in last_year)
{
s1.Points.Add(new DataPoint(running_month, item.NO_BUSINESS));
running_month++;
}
plotModel1.Series.Add(s1);
plotModel1.Axes.Add(new LinearAxis { Position = AxisPosition.Left, IsPanEnabled = false, IsZoomEnabled = false });
plotModel1.Axes.Add(new LinearAxis { Position = AxisPosition.Bottom, IsPanEnabled = false, IsZoomEnabled = false });
return plotModel1;}
The plot generated with hard coded values used for demo. But when the function
List<MonthlyPerformance> last_year = await _apiServices.GetMonthlyPerformance(Settings.AccessToken, Settings.agentCode, year_str);
is called, oxyplot is not being generated. I just get a blank space. I dont get any compilation errors.
I'm using MVVM. Could someone please point out what I'm doing wrong here.
Thanks in advance.

Once await and async were removed, the chart appeared.
I don't think it's the right way to handled the issue. But I was running out of development time.

Related

cannot read property "0" of undefined error

I have a code that pulls information from all excel type files in some folders on google drive. The problem is that there are over 100 files and the code only pulls data from around 30 files and shows the following error: "TypeError: Cannot read property '0' of undefined" The error is in line 12, "console.log(lista_carpetas_ok2[i][0]) // Here, you can see the folder ID in the log."
function listfechas() {
var ss2 = SpreadsheetApp.getActiveSpreadsheet();
var carpetasSheet = ss2.getSheetByName("carpetas");
var lista_carpetas = carpetasSheet.getRange("C2:C" + carpetasSheet.getLastRow()).getValues();
var lista_carpetas_ok2 = lista_carpetas.filter(([a]) => a);
var sheet2 = ss2.getSheetByName("SS23");
sheet2.clear();
sheet2.appendRow(["Folder", "Name", "SMS","rec SMS", "FIT", "rec FIT", "2FIT", "rec 2FIT" ,"3FIT" ,"rec 3FIT" ,"PP" ,"rec PP" ,"2PP" ,"rec 2PP", "3PP", "rec 3PP","SHIP", "rec SHIP", "2SHIP","rec 2SHIP"]);
for (var i = 0; i < 5; i++) {
console.log(lista_carpetas_ok2[i][0]) // Here, you can see the folder ID in the log.
var folderid = lista_carpetas_ok2[i][0];
try {
var parentFolder =DriveApp.getFolderById(folderid);
listFiles(parentFolder,parentFolder.getName())
listSubFolders(parentFolder,parentFolder.getName());
} catch (e) {
Logger.log(e.toString());
}
}
function listSubFolders(parentFolder,parent) {
var childFolders = parentFolder.getFolders();
while (childFolders.hasNext()) {
var childFolder = childFolders.next();
Logger.log("Fold : " + childFolder.getName());
listFiles(childFolder,parent)
listSubFolders(childFolder,parent + "|" + childFolder.getName());
}
}
function listFiles(fold,parent){
var data = [];
var files = fold.getFilesByType(MimeType.GOOGLE_SHEETS);
try {
while (files.hasNext()) {
var file = files.next();
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
var recsms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("B2").getValue();
var fit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("C2").getValue();
var recfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("D2").getValue();
var dfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("E2").getValue();
var recdfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("F2").getValue();
var tfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("G2").getValue();
var rectfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("H2").getValue();
var pp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("I2").getValue();
var recpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("J2").getValue();
var dpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("K2").getValue();
var recdpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("L2").getValue();
var tpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("M2").getValue();
var rectpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("N2").getValue();
var ship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("O2").getValue();
var recship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("P2").getValue();
var dship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("Q2").getValue();
var recdship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("R2").getValue();
var fullRange = sheet2.getRange("A1:Z1001");
fullRange.setVerticalAlignment(DocumentApp.VerticalAlignment.TOP);
data = [
fold.getName(),
file.getName(),
sms,
recsms,
fit,
recfit,
dfit,
recdfit,
tfit,
rectfit,
pp,
recpp,
dpp,
recdpp,
tpp,
rectpp,
ship,
recship,
dship,
recdship,
];
sheet2.appendRow(data);
};
} catch (e) {
// In this modification, when your folder ID cannot be used, that folder ID is skipped. At that time, an error message can be seen in the log.
console.log(e.message);
}
}
}
When I wrote the code, I added catch (e) which I thought skipped the folder if there was no excel file in that folder, but the code stops at folder "QM0201" which does not have an excel file in it.
Does anybody know how I can fix it? I would like the code to run even if some folders don't have an excel files in them, those should just be skipped.
Thank you so much in advance! Any help is appreciated.
To avoid the error, replace
for (var i = 0; i < 5; i++) {
by
for (var i = 0; i < lista_carpetas_ok2.length; i++) {
This might also help to avoid the code to stop at certain folder.
Regarding the error
> Info Cannot read property 'getRange' of null"
This occurs because the spreadsheet hasn't a sheet named fechas
to avoid this error you might add
if(!SpreadsheetApp.open(file).getSheetByName("fechas")) break;
above of
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
if(
Debugging tips:
To verify that the correct values are assigned to lista_carpetas_ok2, add console.log(JSON.stringify(lista_carpetas_ok2)); just below lista_carpetas_ok2 declaration so you can review the values assigned to the variable.
To have more informative logs when an error occurs, instead of
} catch (e) {
Logger.log(e.toString()); // or console.log(e.message);
}
use
} catch (e) {
console.log(e.message, e.stack);
}
This is hardly a cause of the error but who knows, the code has the very unefficient part — 72 calls to the server. It can be greatly improved if you change this:
var sms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("A2").getValue();
var recsms = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("B2").getValue();
var fit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("C2").getValue();
var recfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("D2").getValue();
var dfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("E2").getValue();
var recdfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("F2").getValue();
var tfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("G2").getValue();
var rectfit = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("H2").getValue();
var pp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("I2").getValue();
var recpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("J2").getValue();
var dpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("K2").getValue();
var recdpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("L2").getValue();
var tpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("M2").getValue();
var rectpp = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("N2").getValue();
var ship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("O2").getValue();
var recship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("P2").getValue();
var dship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("Q2").getValue();
var recdship = SpreadsheetApp.open(file).getSheetByName("fechas").getRange("R2").getValue();
To this:
var values = SpreadsheetApp.open(file).getSheetByName("fechas").getRange('A2:R2').getValues().flat();
var [sms,recsms,fit,recfit,dfit,recdfit,tfit,rectfit,pp,recpp,dpp,recdpp,tpp,rectpp,ship,recship,dship,recdship] = values;
It will reduce the quantity of calls to 4!
It should work faster and, if the real cause of the error is exceed of time limit (~6 min) this improvement can help. Try it.
Probably you could simplify the code further. Instead of this:
data = [
fold.getName(),
file.getName(),
sms,
recsms,
fit,
recfit,
dfit,
recdfit,
tfit,
rectfit,
pp,
recpp,
dpp,
recdpp,
tpp,
rectpp,
ship,
recship,
dship,
recdship,
];
You can use this:
var values = SpreadsheetApp.open(file).getSheetByName("fechas").getRange('A2:R2').getValues().flat();
var data = [fold.getName(), file.getName(), ...values];
No need to use the 18 variables, as far as I can see. It barely affects on the speed, though.

In Parse server get() method causes crash

I have a find query with include to get pointer data. It's working fine but if the pointer object does not exist then server crashes.
Here is my query:
var repliesQuery = new Parse.Query("Reply");
repliesQuery.include("author");
repliesQuery.find({
useMasterKey: true
}).then(function(foundMessages) {
var results = [];
for (var i = 0; i < foundMessages.length; i++) {
var rp = {};
rp.title = foundMessages[i].get("title");
rp.description = foundMessages[i].get("description");
var author = foundMessages[i].get("author");
rp.authorId = author.id;
results.push(rp);
}
promise.resolve(results);
});
Everything works fine when the author exists, but if it does not exist then the server crashes.
I tried to add this:
if (author.hasOwnProperty('id')) {
rp.authorId = author.id;
}
But still the issue is not resolved.
Is there any way we can fix this issue?
It's most likely because you're accessing a property of an undefined object, in this case author, in line
rp.authorId = author.id
Like Davi suggests, include a check if author exists.
var repliesQuery = new Parse.Query("Reply");
repliesQuery.include("author");
repliesQuery.find({
useMasterKey: true
}).then(function(foundMessages) {
var results = [];
for (var i = 0; i < foundMessages.length; i++) {
var rp = {};
rp.title = foundMessages[i].get("title");
rp.description = foundMessages[i].get("description");
var author = foundMessages[i].get("author");
if (author) {
rp.authorId = author.id;
}
results.push(rp);
}
promise.resolve(results);
});
Your check
if (author.hasOwnProperty('id')) {
rp.authorId = author.id;
}
also accesses a property of author, so again it would throw an error if author is undefined.

what is the faster and best way to make a few million SOAP requests and save the results into SqlDb

I have a million records in my table. I want to call a soap service and i need to do process in all the records in less than one hour. and besides i should update my table , insert the requests and responses in my other tables. but the code below works on less than 10 records every time i run my app.
I know My code is wrong,, I want to know what is the best way to do it.
static async Task Send( )
{
var results = new ConcurrentDictionary<string, int>();
using (AppDbContext entities = new AppDbContext())
{
var List = entities.Request.Where(x => x.State == RequestState.InitialState).ToList();
Parallel.ForEach(Enumerable.Range(0, List.Count), async index =>
{
var selected = List.FirstOrDefault();
List.Remove( selected );
var res1 = await DoAsyncJob1(selected); ///await
// var res = CallService(selected);
var res2 = await DoAsyncJob2(selected); ///await
var res3 = await DoAsyncJob3(selected); ///await
// var responses = await Task.WhenAll(DoAsyncJob1, DoAsyncJob2, DoAsyncJob3);
// results.TryAdd(index.ToString(), res);
});
}
}
static async Task<int> DoAsyncJob1(Request item)
{
using (AppDbContext entities = new AppDbContext())
{
var bReq = new BankRequest();
bReq.Amount = Convert.ToDecimal(item.Amount);
bReq.CreatedAt = DateTime.Now;
bReq.DIBAN = item.DIBAN;
bReq.SIBAN = item.SIBAN;
entities.BankRequest.Add(bReq);
entities.SaveChanges();
}
return item.Id;
}
static async Task<int> DoAsyncJob2(Request item)
{
using (AppDbContext entities = new AppDbContext())
{
}
return item.Id;
}
static async Task<int> DoAsyncJob3(Request item)
{
using (AppDbContext entities = new AppDbContext())
{
}
return item.Id;
}
Maybe the below lines are wrong :
var selected = List.FirstOrDefault();
List.Remove( selected );
Thanks in advance..
First, it is a bad practice to use async-await within Parallel.For - you introduce only more load to the task scheduler and more overhead.
Second, you are right:
var selected = List.FirstOrDefault();
List.Remove( selected );
is very, very wrong. Your code will behave in a totally unpredictable way, due to the race conditions.

Check cell value before post data to server

I'm having a problem checking cell value after an inline edit and before save data. Part of my ColModel is (without any unnesessary code):
{name:'event_start_date',index:'event_start_date',width:75,align:'center',editable:true,edittype:'text',editoptions:{size:'10',maxlength:'10',
dataInit:function(el){
$(el).mask('9999-99-99');
$(el).datepicker({dateFormat:'yy-mm-dd',
beforeShow: function(input, instance){instance.dpDiv.css({marginTop: '1px'});}})
}}
},
{name:'event_start_time',index:'event_start_time',width:70,align:'center',editable:true,edittype:'text',editoptions:{size:'8',maxlength:'8',
dataInit:function(el){$(el).mask('99:99:99');}}
},
{name:'event_end_date',index:'event_end_date',width:75,align:'center',editable:true,edittype:'text',editoptions:{size:'10',maxlength:'10',
dataInit:function(el){
$(el).mask('9999-99-99');
$(el).datepicker({dateFormat:'yy-mm-dd',
beforeShow: function(input, instance){instance.dpDiv.css({marginTop: '1 px'});}})
}}
},
{name:'event_end_time',index:'event_end_time',width:70,align:'center',editable:true,edittype:'text',editoptions:{size:'8',maxlength:'8',
dataInit:function(el){$(el).mask('99:99:99');}}
},
{name:'event_dur_calc',index:'event_dur_calc',width:90,align:'center',editable:false,edittype:'text',sorttype:'date',editoptions:{size:'10',maxlength:'10'}
}
I'm using double click to get inline edit mode. After user make some changes into date/time fields, new value calculated for cell "event_dur_calc":
$('#'+rowId+'_event_start_date').focusout(function(){recalc_dur(rowId);});
$('#'+rowId+'_event_start_time').focusout(function(){recalc_dur(rowId);});
$('#'+rowId+'_event_end_date').focusout(function(){recalc_dur(rowId);});
$('#'+rowId+'_event_endt_time').focusout(function(){recalc_dur(rowId);});
Functions fo calculating new time:
function mktime(){
var i = 0, d = new Date(), argv = arguments, argc = argv.length;
var dateManip = {
0: function(tt){ return d.setHours(tt); },
1: function(tt){ return d.setMinutes(tt); },
2: function(tt){ return d.setSeconds(tt); },
3: function(tt){ return d.setMonth(parseInt(tt)-1); },
4: function(tt){ return d.setDate(tt); },
5: function(tt){ return d.setYear(tt); }
};
for( i = 0; i < argc; i++ ){
if(argv[i] && isNaN(argv[i])){
return false;
} else if(argv[i]){
if(!dateManip[i](argv[i])){
return false;
}
}
}
return Math.floor(d.getTime()/1000);
};
function recalc_dur(rowId){
var event_start_date_txt = $('#'+rowId+'_event_start_date').val();
var event_start_time_txt = $('#'+rowId+'_event_start_time').val();
var event_end_date_txt = $('#'+rowId+'_event_end_date').val();
var event_end_time_txt = $('#'+rowId+'_event_end_time').val();
if (event_end_date_txt=='0000-00-00'){
$('#'+rowId+'_event_dur_calc').val('0000:00:00');
}else{
var start_d_pices = event_start_date_txt.split('-');
var start_t_pices = event_start_time_txt.split(':');
var end_d_pices = event_end_date_txt.split('-');
var end_t_pices = event_end_time_txt.split(':');
var start_time = mktime(start_t_pices[0], start_t_pices[1], start_t_pices[2], start_d_pices[1], start_d_pices[2], start_d_pices[0]);
var end_time = mktime(end_t_pices[0], end_t_pices[1], end_t_pices[2], end_d_pices[1], end_d_pices[2], end_d_pices[0]);
var delta = end_time-start_time;
var secs = delta % 60;
delta = (delta - secs) / 60;
if (secs.toString().length==1) var new_dur = ':0'+secs; else var new_dur = ':'+secs;
var mins = delta % 60;
delta = (delta - mins) / 60;
if (mins.toString().length==1) new_dur = ':0'+mins+new_dur; else new_dur = ':'+mins+new_dur;
var hours = delta;
if (hours.toString().length==1){new_dur = '000'+hours+new_dur;
}else if (hours.toString().length==2){new_dur = '00'+hours+new_dur;
}else if (hours.toString().length==3){new_dur = '0'+hours+new_dur;
}else new_dur = hours+new_dur;
$('tr[id=\"'+rowId+'\"] > td[aria-describedby=\"dfr_event_dur_calc\"]').html(new_dur);
}
}
If the new calculating time will be below zero (when start date/time is greater than end date/time), modal window with alert message is appers and data can't be saved and posted on server.
Is there any event in inline edit mode that fires before posting data, that I can use to check new calculating value to prevent incorrect data will be saved?
The current code of jqGrid on github contains beforeSaveRow callback function which will be called before saving. The changes was made after publishing of jqGrid 4.5.2, but the feature will be exist in the next version (>4.5.2) of jqGrid. So if you don't want use developer sources from github you can use the standard validation way: usage editrules with custom: true and custom_func which do the validation.

How to pass a input value into a function using GAS

I will try and keep this brief. I am attempting to make a google web app in google spreadsheet that will allow me to enter a values for min and max.
I have been able to create the GUI and add it to the panel. But I can't seem to pass the integer being entered into another function. I've tried everything, I'm relatively new to creating Google Script so I'm sorry if this comes across as a bit of a noobish problem.
Here is all the code so far :
function onOpen() {
var ss = SpreadsheetApp.getActive();
var menuEntries = [];
menuEntries.push({name: "Open Dialog", functionName: "showDialog"});
ss.addMenu("Min/Max", menuEntries);
}
//creating a panel to add the min and max of low to high for scoring
function showDialog() {
max = 10;
var app = UiApp.createApplication();
app.setTitle("My Applicaition");
var panel = app.createVerticalPanel();
var textBox = app.createTextBox();
var label = app.createLabel("Set the min value for 'Low'");
//had to create a hidden element with id="min" for a global value that can be updated
var min = app.createHidden().setValue('0').setName('min').setId('min');
textBox.setName('myTextBox').setId('myTextBox');
var button = app.createButton('Submit');
panel.add(label);
panel.add(textBox);
panel.add(min);
panel.add(button);
//click handler for setting the value of min to the new value
var clickHandler = app.createServerClickHandler("responedToSubmit");
button.addClickHandler(clickHandler);
clickHandler.addCallbackElement(panel);
app.add(panel);
var doc = SpreadsheetApp.getActive();
doc.show(app);
}
function responedToSubmit(e) {
var app = UiApp.getActiveApplication();
var textBoxValue = e.parameter.myTextBox;
Logger.log(e.parameter.min);
if (typeof textBoxValue != "number") {
var num = parseInt(textBoxValue);
app.getElementById('min').setValue(num);
Logger.log("textBoxValue is = "+textBoxValue+"\n min value is = "+e.parameter.min);
} else {
throw "value needs to be set as number";
}
return app.close();
}
This is where I believe things aren't going according to plan :
function responedToSubmit(e) {
var app = UiApp.getActiveApplication();
var textBoxValue = e.parameter.myTextBox;
Logger.log(e.parameter.min);
if (typeof textBoxValue != "number") {
var num = parseInt(textBoxValue);
app.getElementById('min').setValue(num);
Logger.log("textBoxValue is = "+textBoxValue+"\n min value is = "+e.parameter.min);
} else {
throw "value needs to be set as number";
}
return app.close();
}
I find that each time I test the .setValue() will not update the value of 'min' and I cannot see why. Can you please help?
You need to add textBox element to callBack elements list of your clickHandler.
Try this:
//click handler for setting the value of min to the new value
var clickHandler = app.createServerClickHandler("responedToSubmit");
clickHandler.addCallbackElement(panel);
clickHandler.addCallbackElement(textBox);
button.addClickHandler(clickHandler);
app.add(panel);

Resources