Search code examples
locationgtkvala

gweather_location_get_city_name: assertion 'loc != NULL' failed


I'm trying to fetch my location using GeoClue and GWeather.

enter image description here

I want to display the name of my city in the blank space.

public class Epoch.LabelsGrid : Gtk.Grid {
    public Gtk.Label face1_label;
    public Gtk.Label face2_label;
    public Gtk.Label face3_label;
    public Gtk.Label face4_label;
    
    public GClue.Location? geo_location {get; private set; default = null;}
    public GWeather.Location location;
    private GClue.Simple simple;
    
    construct {
        face1_label = new Gtk.Label ("");
        face1_label.label = dgettext ("libgweather-locations", location.get_city_name ());
        face1_label.halign = Gtk.Align.CENTER;
        face1_label.hexpand = true;
        face1_label.margin_top = 6;
        face1_label.set_ellipsize (END);
        face1_label.set_max_width_chars (12);
        
        face2_label = new Gtk.Label ("Paris");
        face2_label.set_markup ("<span font_desc='Inter 14'><b>Paris</b></span>");
        face2_label.halign = Gtk.Align.CENTER;
        face2_label.hexpand = true;
        face2_label.margin_top = 6;
        face2_label.set_ellipsize (END);
        face2_label.set_max_width_chars (12);
        
        face3_label = new Gtk.Label ("London");
        face3_label.set_markup ("<span font_desc='Inter 14'><b>London</b></span>");
        face3_label.halign = Gtk.Align.CENTER;
        face3_label.hexpand = true;
        face3_label.margin_top = 6;
        face3_label.set_ellipsize (END);
        face3_label.set_max_width_chars (12);
        
        face4_label = new Gtk.Label ("New York");
        face4_label.set_markup ("<span font_desc='Inter 14'><b>New York</b></span>");
        face4_label.halign = Gtk.Align.CENTER;
        face4_label.hexpand = true;
        face4_label.margin_top = 6;
        face4_label.set_ellipsize (END);
        face4_label.set_max_width_chars (12);
        }
        
    public async void seek () {
        try {
            simple = yield new GClue.Simple ("com.gihhub.Suzie97.epoch", GClue.AccuracyLevel.CITY, null);
        } catch (Error e) {
            warning ("Failed to connect to GeoClue2 service: %s", e.message);
            return;
        }
        
        simple.notify["location"].connect (() => {
            on_location_updated.begin ();
        });
        
        on_location_updated.begin ();
    }
    
    public async void on_location_updated () {
        geo_location = simple.get_location ();
        
        location = location.find_nearest_city (geo_location.latitude, geo_location.longitude);
    }
}

This is the code.

The code compiles but while executing the program, (com.github.Suzie97.epoch:30386): GWeather-CRITICAL **: 13:21:03.758: gweather_location_get_city_name: assertion 'loc != NULL' failed this warning is displayed.

I found this code snippet on an app by Daniel Fore called Nimbus (Link to nimbus repo)

 public void on_location_updated (double latitude, double longitude) {
        location = GWeather.Location.get_world ();
        location = location.find_nearest_city (latitude, longitude);
        if (location != null) {
            weather_info.location = location;
            weather_info.update ();
            stack.visible_child_name = "weather";
        }
    }

Do I need to do something similar to this?


Solution

  • According to the error message, gweather_location_get_city_name () is emitting an error because the location is NULL (loc != NULL is false). Look at where you're calling get_city_name (). It's at the very top of your constructor, before location is set to anything. You need to wait until you have a location before you try to use it.

    Then you should use something like the Nimbus code. It handles the case when simple.get_location () returns NULL (if it can't find your location), and also initializes the GWeather location so it can call find_nearest_city ().