Categories
discuss

React.js, wait for setState to finish before triggering a function?

Here’s my situation:

  • on this.handleFormSubmit() I am executing this.setState()
  • inside this.handleFormSubmit(), I am calling this.findRoutes(); – which depends on the successful completion of this.setState()
  • this.setState(); does not complete before this.findRoutes is called…
  • How do I wait for this.setState() inside of this.handleFormSubmit() to finish before calling this.findRoutes()?

A subpar solution:

  • putting this.findRoutes() in componentDidUpdate()
  • this is not acceptable because there will be more state changes unrelated the findRoutes() function. I don’t want to trigger the findRoutes() function when unrelated state is updated.

Please see code snippet below:

handleFormSubmit: function(input){
                // Form Input
                this.setState({
                    originId: input.originId,
                    destinationId: input.destinationId,
                    radius: input.radius,
                    search: input.search
                })
                this.findRoutes();
            },
            handleMapRender: function(map){
                // Intialized Google Map
                directionsDisplay = new google.maps.DirectionsRenderer();
                directionsService = new google.maps.DirectionsService();
                this.setState({map: map});
                placesService = new google.maps.places.PlacesService(map);
                directionsDisplay.setMap(map);
            },
            findRoutes: function(){
                var me = this;
                if (!this.state.originId || !this.state.destinationId) {
                    alert("findRoutes!");
                    return;
                }
                var p1 = new Promise(function(resolve, reject) {
                    directionsService.route({
                        origin: {'placeId': me.state.originId},
                        destination: {'placeId': me.state.destinationId},
                        travelMode: me.state.travelMode
                    }, function(response, status){
                        if (status === google.maps.DirectionsStatus.OK) {
                            // me.response = response;
                            directionsDisplay.setDirections(response);
                            resolve(response);
                        } else {
                            window.alert('Directions config failed due to ' + status);
                        }
                    });
                });
                return p1
            },
            render: function() {
                return (
                    <div className="MapControl">
                        <h1>Search</h1>
                        <MapForm
                            onFormSubmit={this.handleFormSubmit}
                            map={this.state.map}/>
                        <GMap
                            setMapState={this.handleMapRender}
                            originId= {this.state.originId}
                            destinationId= {this.state.destinationId}
                            radius= {this.state.radius}
                            search= {this.state.search}/>
                    </div>
                );
            }
        });

Answer

setState() has an optional callback parameter that you can use for this. You only need to change your code slightly, to this:

// Form Input
this.setState(
  {
    originId: input.originId,
    destinationId: input.destinationId,
    radius: input.radius,
    search: input.search
  },
  this.findRoutes         // here is where you put the callback
);

Notice the call to findRoutes is now inside the setState() call, as the second parameter.
Without () because you are passing the function.

Categories
discuss

What is the conventional Java exception for “Too Many Results”

I am writing a generic API that takes parameters and returns results. I expect that if the data is consistent, only one result will be returned for an ID. If I get 1 result, I return it. If I get 0 results, I can throw “MissingResourceException” or “NoSuchElementException” etc. However, if I get multiple results, what should I throw? I have looked at the obvious places (Oracle/Java API documentation, Googling it, and of course, StackOverflow), but didn’t find one.

Please note that I may not control the data, so the “the data should have been good/police your data” advice, while valid, will not help me.

Any help is appreciated.

Answer

Joshua Bloch’s Effective Java says in Item 60 (Favor to use standard exceptions):

Also, feel free to subclass an existing exception if you want to add a bit more failure-capture information (Item 63).

So, I vote for one of IllegalStateException or YourOwnException (with additional failure-related info).

Categories
discuss

Picasso Images are loading slow in android, why?

The images from the Picasso libery are loading in the emulater after a few clicks and very slow. Why are they loading so slow? And what do I have to do to make them load faster. I tried it with png files and jpg.

Java code

 private int a;
 ImageView ivImageFromUrl;


 protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    ivImageFromUrl=(ImageView)findViewById(R.id.iv_image_from_url);

}

 public void buttonOnClick(View v)  {
    // do something when the button is clicked
    Button button = (Button) v;

    a = (byte) (Math.random() * 5);

    switch (a) {
        case 1:
            Picasso.with(getApplicationContext()).load("http://icons.iconarchive.com/icons/crountch/one-piece-jolly-roger/72/Luffys-flag-2-icon.png").into(ivImageFromUrl);
          break;
        case 2:
            Picasso.with(getApplicationContext()).load("http://i40.tinypic.com/2i8xait.jpg").into(ivImageFromUrl);
            break;
        case 3:
            Picasso.with(getApplicationContext()).load("http://i41.tinypic.com/2i8xahh.jpg").into(ivImageFromUrl);
            break;
        case 4:
            Picasso.with(getApplicationContext()).load("http://i42.tinypic.com/2i8xahk.jpg").into(ivImageFromUrl);
            break;
        case 5:
            Picasso.with(getApplicationContext()).load("http://i40.tinypic.com/2i8xagp.jpg").into(ivImageFromUrl);
            break;
    }
}
}

XML

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    android:id="@+id/textView2" />

<TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Image text"
    android:id="@+id/textView"
    android:layout_below="@+id/textView2"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="82dp" />

<Button
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Image"
    android:id="@+id/button"
    android:onClick="buttonOnClick"
    android:layout_below="@+id/textView"
    android:layout_centerHorizontal="true"
    android:layout_marginTop="41dp" />

<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:id="@+id/iv_image_from_url"
    android:layout_alignParentBottom="true"
    android:layout_alignRight="@+id/textView"
    android:layout_alignEnd="@+id/textView"
    android:layout_marginBottom="106dp" />

Answer

If your images are too large, then it may take some time.

If you need to show profile picture, whose size in your layout is 350×350, then why load full image. Re-size the image as per your requirement.

Picasso.with(getApplicationContext()).load(filePath).resize(400,400).centerCrop().into(imageView);
Categories
discuss

How to remove a modal page from NavigationStack in Xamarin.Forms

Here’s an example for my Navigation:

LoginPage ( Login_Click  ) -> MainPage   | Block BackButton
MainPage  ( Logout_Click ) -> LoginPage  | Block going back to the MainPage

Currently I am using this code to show the MainPage after a successful login.

 await Navigation.PushModalAsync(new MainPage());

I DON’T want the users to go back by hitting the PreviousButton(Android) to return to the LoginPage.

Same story when logging out.

Is there a way to remove the LoginPage from the NavigationStack after a successful login (and remove the MainPage when logged out) ?

NOTE:

This is modal. I am not using a NavigationPage.

Answer

You are looking for PopToRootAsync. So your user enters required info and they tap a login button, you perform your login verification and if success you set a new MainPage and then PopToRootAsync which pops all but the root Page off the navigation stack.

Update: Due to the way PopToRootAsync is done across the various platforms, you need to start from a NavigationPage but can remove it as your root page after your login process.

So in your Application constructor, instead of just creating your LoginPage, place it into a NavigationPage but hide the navigation bar so it does not effect your LoginPage screen layout:

public App()
{
    var navPage = new NavigationPage(new LoginPage());
    NavigationPage.SetHasNavigationBar(navPage.CurrentPage, false);
    MainPage = navPage;
}

Then within your LoginPage you can set the Application.Current.MainPage to any Page class (does not have to be a NavigationPage) and then PopToRootAsync to get to it and totally remove your LoginPage from the navigation hierarchy.

public partial class LoginPage : ContentPage
{
    public LoginPage()
    {
        InitializeComponent();
        loginDone.Clicked += OnLoginClick;
    }
    async void OnLoginClick(object sender, EventArgs e)
    {
        // If Login is complete/successful - set new root page
        if (YourLoginMethod()) {
            Application.Current.MainPage = new MainApplicationPage();
            // Pops all but the root Page off the navigation stack, with optional animation.
            await Navigation.PopToRootAsync(true);
        }
    }
}

Note: Tested this technique only on iOS and Android

Categories
discuss

How to access the Wikidata SPARQL interface from Java?

I am trying to query all instances of an entity from Wikidata. I found out that currently the only way to do this is to use the SPARQL endpoint.

I found an example query which does about what I want to do and successfully executed it from the Web interface. Unfortunately I can’t seem to be able to execute it from within my Java code. I am using the openRDF SPARQL library. Here is my relevant code:

SPARQLRepository sparqlRepository = new SPARQLRepository(
        "https://query.wikidata.org/");
SPARQLConnection sparqlConnection = new SPARQLConnection(
        sparqlRepository);

String query = "SELECT ?s ?desc ?authorlabel (COUNT(DISTINCT ?sitelink) as ?linkcount) WHERE {"
        + "?s wdt:P31 wd:Q571 ."
        + "?sitelink schema:about ?s ."
        + "?s wdt:P50 ?author"
        + "OPTIONAL { ?s rdfs:label ?desc filter (lang(?desc) = "en"). }"
        + "OPTIONAL {"
        + "?author rdfs:label ?authorlabel filter (lang(?authorlabel) = "en")."
        + "}"
        + "} GROUP BY ?s ?desc ?authorlabel ORDER BY DESC(?linkcount)";

TupleQuery tupleQuery = sparqlConnection.prepareTupleQuery(
        QueryLanguage.SPARQL, query);
System.out.println("Result for tupleQuery" + tupleQuery.evaluate());

And here is the response I’m receiving:

Exception in thread "main" org.openrdf.query.QueryEvaluationException: <html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.9.4</center>
</body>
</html>
    at org.openrdf.repository.sparql.query.SPARQLTupleQuery.evaluate(SPARQLTupleQuery.java:59)
    at main.Test.main(Test.java:72)
Caused by: org.openrdf.repository.RepositoryException: <html>
<head><title>405 Not Allowed</title></head>
<body bgcolor="white">
<center><h1>405 Not Allowed</h1></center>
<hr><center>nginx/1.9.4</center>
</body>
</html>
    at org.openrdf.http.client.HTTPClient.handleHTTPError(HTTPClient.java:953)
    at org.openrdf.http.client.HTTPClient.sendTupleQueryViaHttp(HTTPClient.java:718)
    at org.openrdf.http.client.HTTPClient.getBackgroundTupleQueryResult(HTTPClient.java:602)
    at org.openrdf.http.client.HTTPClient.sendTupleQuery(HTTPClient.java:367)
    at org.openrdf.repository.sparql.query.SPARQLTupleQuery.evaluate(SPARQLTupleQuery.java:52)
    ... 1 more

Normally I would assume that this means I need an API key of sorts, but the Wikidata API appears to be completely open. Did I make a mistake setting up my connection?

Answer

The proper endpoint URL for Wikidata is https://query.wikidata.org/sparql – you’re missing the last bit.

In addition, I noticed a few glitches in your code. First of all, you’re doing this:

SPARQLConnection sparqlConnection = new SPARQLConnection(sparqlRepository);

This should be this:

RepositoryConnection sparqlConnection = sparqlRepository.getConnection();

Always retrieve your connection object from the Repository object using getConnection() – this means resources are shared and the Repository can close ‘dangling’ connections if necessary.

Secondly: you can’t print out the result of a query like this:

System.out.println("Result for tupleQuery" + tupleQuery.evaluate());

If you wish to print out the result to System.out you should instead do something like this:

tupleQuery.evaluate(new SPARQLResultsTSVWriter(System.out));

Or (if you wish to customize the result a bit more):

for (BindingSet bs : QueryResults.asList(tupleQuery.evaluate())) {
    System.out.println(bs);
}

For what it’s worth – with the above changes the query request runs, but it appears your query is too ‘heavy’ for Wikidata – at least I got a timeout error from the server. Try a simpler query though, and you’ll see the code works.

Source: stackoverflow
Text is available under the Creative Commons Attribution-ShareAlike License; additional terms may apply. By using this site, you agree to the Privacy Policy, and Copyright Policy. Content is available under CC BY-SA 3.0 unless otherwise noted. The answers/resolutions are collected from stackoverflow, are licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0 © No Copyrights, All Questions are retrived from public domain..