I'm having problems implementing the webView's DOMContentLoaded event within my view model. I want to execute the code on the web page after the DOMContentLoaded event. I read the documentation about the event here, https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.webview.domcontentloaded, however I'm having problems implementing it. Below is the code I currently have:
WebView webView = new WebView();
webView.Navigate(new Uri(url));
webView.DOMContentLoaded += DOMContentLoaded;
// event handling for dom content loaded
public event TypedEventHandler<WebView, WebViewDOMContentLoadedEventArgs> DOMContentLoaded
{
}^ This is from the documentation
Currently, it's giving me an error that says, "event property must have both add and remove accessors.". I understand how to use events in the XAML because it's super easy and does most of the work for me, but since I'm using the webview in the view model (to scrape and get some information on a web page), I need to wait for the page to load and then do the scraping. How can I do that in the view model?
EDIT:
Great Question. So in the ViewModel I'm using the WebView as a scraper. Here are the functions that will use it and some more details.
public async void UPCSearch(object sender, KeyRoutedEventArgs e)
{
if (e.Key == Windows.System.VirtualKey.Enter)
{
/*
// search Walmart
try {
await searchWalmartNF();
//if (!found || !walmartInformation)
} catch (HttpRequestException httpException) {
Debug.WriteLine("HTTP exception caught.");
Debug.WriteLine(httpException);
} catch (Exception exception) {
Debug.WriteLine("Exception caught.");
Debug.WriteLine(exception);
}*/
// search Target
try {
**await searchTargetNF();**
} catch (HttpRequestException httpException) {
Debug.WriteLine("HTTP exception caught.");
Debug.WriteLine(httpException);
} catch (Exception exception) {
Debug.WriteLine("Exception caught.");
Debug.WriteLine(exception);
}
// search CVS
try
{
**await searchCVSNF();**
}
catch (HttpRequestException httpException)
{
Debug.WriteLine("HTTP exception caught.");
Debug.WriteLine(httpException);
}
catch (Exception exception)
{
Debug.WriteLine("Exception caught.");
Debug.WriteLine(exception);
}
// if a price was found
if (found)
{
operationClicked = false;
calculated = true;
hasDecimal = false;
displayText = onlinePrice.ToString();
textblockPrice = onlinePrice.ToString() + onlineAbbrev;
}
else
{
var messageDialog = new MessageDialog("No price was found online.");
await messageDialog.ShowAsync();
}
// reset found
found = false;
}
}
public async Task **searchTargetNF()**
{
try
{
string targetURL = "https://www.target.com/s?searchTerm=";
url = (targetURL + upc);
webView.Navigate(new Uri(url));
webView.DOMContentLoaded += DOMContentLoaded;
//super.onPageFinished(webView, url);
// delay to ensure navigation completes
**await Task.Delay(6500);**
string html = await webView.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
var text = html;
var doc = new HtmlDocument();
doc.LoadHtml(text);
var price = doc.DocumentNode.SelectSingleNode("//*[@id=\"mainContainer\"]/div[3]/div[2]/div/div[1]/div[3]/div/ul/li/div/div[2]/div/div/div/div[2]/span");
//var price = doc.DocumentNode.SelectNodes("//div[@class='styles__StyledPricePromoWrapper-e5kry1-12 gzebgK']");
Debug.WriteLine("Target price found:");
Debug.WriteLine(price.InnerText);
}
catch (HttpRequestException httpException)
{
Debug.WriteLine("HTTP exception caught.");
Debug.WriteLine(httpException);
}
catch (Exception exception)
{
Debug.WriteLine("Exception caught.");
Debug.WriteLine(exception);
}
}
Currently, the searchWalmart() function uses Walmart's API, so that doesn't need the WebView. However, searchTargetNF() uses the WebView to scrape, and needs to wait for the page to load to scrape the information on the page. It does get the information it needs with the wait timer, but it isn't practical to wait 6.5s for each web page that it views to get the information. The variables such as UPC are entered in from the UI side and the ViewModel works with that info to return product prices back to the UI.
The goal is to execute the code in searchTargetNF() after the DOMContentLoaded event, and return product prices to the UI side.