Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to correctly parse a JSON #35

Closed
lbhack opened this issue Jan 24, 2023 · 9 comments
Closed

How to correctly parse a JSON #35

lbhack opened this issue Jan 24, 2023 · 9 comments
Assignees
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed

Comments

@lbhack
Copy link

lbhack commented Jan 24, 2023

Screenshot 1401-11-04 at 13 08 48

hi i want to access the field temp_C in json always getting empty value request using the code below :

/*

*/

/* NAppGUI Hello World */

#include "nappgui.h"
#include "inet.h"
#include "httpreq.h"
#include "json.h"

typedef struct _app_t App;
typedef struct _currentCondition_t CurrentCondition;
typedef struct WeatherDesc {
char_t value[20];
} WeatherDesc;

typedef struct WeatherIconUrl {
char_t value[100];
} WeatherIconUrl;

struct _currentCondition_t {
uint32_t FeelsLikeC;
uint32_t FeelsLikeF;
uint32_t cloudcover;
uint32_t humidity;
char_t localObsDateTime[20];
char_t observation_time[20];
real32_t precipInches;
real32_t precipMM;
uint32_t pressure;
real32_t pressureInches;
uint32_t temp_C;
uint32_t temp_F;
uint32_t uvIndex;
uint32_t visibility;
uint32_t visibilityMiles;
uint32_t weatherCode;
WeatherDesc weatherDesc[1];
WeatherIconUrl weatherIconUrl[1];
char_t winddir16Point[5];
uint32_t winddirDegree;
uint32_t windspeedKmph;
uint32_t windspeedMiles;
};

struct _app_t
{
Window *window;
TextView *text;

};
/---------------------------------------------------------------------------/

/---------------------------------------------------------------------------/

static void i_OnButton(App *app, Event *e)
{
Stream *gdata = NULL;
CurrentCondition *json=NULL;

Http *ht = http_secure("wttr.in",443);
if(http_get(ht, "/spain?format=j1", NULL, 0, NULL) == TRUE)
{
    //app->buff = str_printf("%d\n",http_response_status(ht));
    textview_printf(app->text, "%d\n",http_response_status(ht));
    gdata = stm_memory(4096);
    if (http_response_body(ht, gdata, NULL) == FALSE)
        stm_close(&gdata);
}
http_destroy(&ht);
dbind(CurrentCondition, uint32_t, temp_C);
json = json_read(gdata,NULL, CurrentCondition);
textview_printf(app->text,"The temp_c : %d\n",json->temp_C);
json_destroy(&json, CurrentCondition);
unref(e);

}
static Panel *i_panel(App *app)
{
Panel *panel = panel_create();
Layout *layout = layout_create(1, 3);
Label *label = label_create();
Button *button = button_push();
TextView *text = textview_create();
app->text = text;
label_text(label, "Hello!, I'm a label");
button_text(button, "Click Me!");
button_OnClick(button, listener(app, i_OnButton, App));
layout_label(layout, label, 0, 0);
layout_button(layout, button, 0, 1);
layout_textview(layout, text, 0, 2);
layout_hsize(layout, 0, 250);
layout_vsize(layout, 2, 200);
//layout_hsize(layout, 2, 200);
layout_margin(layout, 5);
layout_vmargin(layout, 0, 5);
layout_vmargin(layout, 1, 5);
panel_layout(panel, layout);
return panel;
}

/---------------------------------------------------------------------------/

static void i_OnClose(App *app, Event *e)
{
osapp_finish();
unref(app);
unref(e);
}

/---------------------------------------------------------------------------/

static App *i_create(void)
{
App *app = heap_new0(App);
Panel *panel = i_panel(app);
app->window = window_create(ekWINDOW_STD | ekWINDOW_RESIZE);
window_panel(app->window, panel);
window_title(app->window, "Hello, World!");
//window_size(app->window,s2df(800.0,400.0));
window_origin(app->window, v2df(500, 200));
window_OnClose(app->window, listener(app, i_OnClose, App));
window_show(app->window);
return app;
}

/---------------------------------------------------------------------------/

static void i_destroy(App **app)
{
window_destroy(&(*app)->window);
heap_delete(app, App);
}

/---------------------------------------------------------------------------/

#include "osmain.h"
osmain(i_create, i_destroy, "", App)

Screenshot 1401-11-04 at 23 45 08

curl --silent wttr.in/spain?format=j1 | grep -i -o ""temp_c":.*[0-9]" --color=auto | sed 's/"//g'

@frang75 frang75 changed the title access json temp_C from wttr.in How to correctly parse a JSON Jan 24, 2023
@frang75
Copy link
Owner

frang75 commented Jan 24, 2023

Hi @lbhack !
Here is a small demo of how to correctly parse the JSON of your example.

json

/* NAppGUI Console Application */
    
#include "coreall.h"
#include "httpreq.h"
#include "json.h"
#include "inet.h"

/* Your C structs MUST follow the same organization as JSON, for automatic parsing. */
typedef struct _condition_t Condition;
typedef struct _weather_t Weather;

/* Every Condition has several fields, but we are only interested in 'temp_C' what is of string type */
struct _condition_t 
{
    String *temp_C;
};

/* SetUp arrays and sets for Condition structure */
DeclSt(Condition);

/* The global JSON has an ARRAY of objects of type Condition called 'current_condition' */
struct _weather_t
{
    ArrSt(Condition) *current_condition;
};

/*---------------------------------------------------------------------------*/

/* Data binding ONLY once when application starts */
/* https://nappgui.com/en/core/dbind.html */
/* https://nappgui.com/en/inet/json.html */
static void i_dbind(void)
{
    dbind(Condition, String*, temp_C);
    dbind(Weather, ArrSt(Condition)*, current_condition);
}

/*---------------------------------------------------------------------------*/

static Weather *i_get_weather(void)
{
    Weather *weather = NULL;

    Http *ht = http_secure("wttr.in",443);
    if(http_get(ht, "/madrid?format=j1", NULL, 0, NULL) == TRUE)
    {
        Stream *gdata = stm_memory(4096);
        if (http_response_body(ht, gdata, NULL) == TRUE)
        {
            /* We have the JSON string --> Parse to C Struct */
            weather = json_read(gdata, NULL, Weather);
        }

        /* ALWAYS you have to destroy the stream (not only if respose fails) */
        stm_close(&gdata);
    }
    
    http_destroy(&ht);
    return weather;
}

/*---------------------------------------------------------------------------*/

/* Console application created with */
/* commandApp("SimpleJson" "simplejson" "osapp;inet" NRC_PACKED) */
int main(int argc, char *argv[])
{
    uint32_t i = 0;
    unref(argc);
    unref(argv);
    core_start();
    inet_start();

    /* First, data binding, just once */
    i_dbind();

    for(i = 0; i < 10; ++i)
    {
        Weather *weather = i_get_weather();
        /* Weather can be obtained from REST-API */
        if (weather != NULL)
        {
            if(weather->current_condition != NULL)
            {
                /* We are interested in first element of 'current_condition' */
                if(arrst_size(weather->current_condition, Condition) > 0)
                {
                    const Condition *condition = arrst_first_const(weather->current_condition, Condition);
                    bstd_printf("temp_C: %s\n", tc(condition->temp_C));
                }
            }

            /* Data Binding knows how to completely destroy a binded object */
            /* https://nappgui.com/en/core/dbind.html#h4 */
            dbind_destroy(&weather, Weather);
        }
    }

    core_finish();
    inet_finish();
    return 0;
}
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
temp_C: 2
[23:20:21] [OK] Heap Memory Staticstics
[23:20:21] ============================
[23:20:21] Total a/dellocations: 273, 273
[23:20:21] Total bytes a/dellocated: 1300184, 1300184
[23:20:21] Max bytes allocated: 108676
[23:20:21] Effective reallocations: (0/0)
[23:20:21] Real allocations: 2 pages of 65536 bytes
[23:20:21]                   10 pages greater than 65536 bytes
[23:20:21] ============================
[23:20:21] Config: Debug

@frang75 frang75 added the help wanted Extra attention is needed label Jan 24, 2023
@frang75 frang75 self-assigned this Jan 24, 2023
@lbhack
Copy link
Author

lbhack commented Jan 24, 2023

mucha gracias

@frang75 frang75 added the documentation Improvements or additions to documentation label Jan 26, 2023
@lbhack
Copy link
Author

lbhack commented Jan 26, 2023

Screenshot 1401-11-06 at 23 33 00

hi and if i want to access the array country from array nearest_area what i need to change ?

@frang75
Copy link
Owner

frang75 commented Jan 27, 2023

I'm sure you can do it yourself, following the example I gave you.

@lbhack
Copy link
Author

lbhack commented Jan 27, 2023

ok thanks i get it .

@lbhack
Copy link
Author

lbhack commented Jan 27, 2023

here i finished the mini project with code about Weather Information :

/*

  • NAppGUI Cross-platform C SDK
  • 2015-2022 jose jaramillo
  • MIT Licence
  • File: main.c

*/

/* NAppGUI Weather Info */

#include "nappgui.h"
#include "inet.h"
#include "httpreq.h"
#include "json.h"
/* Define App struct, which contains the main window, text view, and other elements /
typedef struct _app_t App;
/
Your C structs MUST follow the same organization as JSON, for automatic parsing. /
typedef struct _condition_t Condition;
typedef struct _weather_t Weather;
typedef struct val Values;
typedef struct nearest_area Nearestarea;
typedef struct count Country;
/
Every Condition has several fields, but we are only interested in 'temp_C' what is of string type */
struct count
{
String *value; //value of country
};
struct val
{
String *value; // value Weather description
};
struct _condition_t
{
String *pressure;
String *temp_F;
String *temp_C;
ArrSt(Values) *weatherDesc;

};
struct nearest_area
{
ArrSt(Country) *country;
};

/* SetUp arrays and sets for Condition structure /
DeclSt(Condition);
DeclSt(Values);
DeclSt(Nearestarea);
DeclSt(Country);
/
The global JSON has an ARRAY of objects of type Condition called 'current_condition' */
struct _weather_t
{
// ArrSt(Condition) *nearest_area;
ArrSt(Condition) *current_condition;
ArrSt(Nearestarea) *nearest_area;

};

struct _app_t
{
Window *window;
TextView *text;
String *lop;
String count;
Edit country;
};
/
---------------------------------------------------------------------------
/

static void init_bind()
{

dbind(Condition, String*, temp_C);
dbind(Condition, String*, pressure);
dbind(Condition, String*, temp_F);
dbind(Values, String*, value);
dbind(Condition, ArrSt(Values)* , weatherDesc);
dbind(Weather, ArrSt(Condition)*, current_condition);
dbind(Country, String*, value);
dbind(Nearestarea, ArrSt(Country)*, country);
dbind(Weather, ArrSt(Nearestarea)*, nearest_area);


/*---------------------------------------------------------------------------*/

}
static uint32_t i_OnButton(App *app)
{
Stream *gdata = NULL;
Weather *weather = NULL;;
String *path;

Http *ht = http_secure("wttr.in",443);
path = str_printf("/%s?format=j1",app->count);
if(http_get(ht, tc(path), NULL, 0, NULL) == TRUE)
{
    gdata = stm_memory(4096);
    if (http_response_body(ht, gdata, NULL) == FALSE)
        stm_close(&gdata);
}
http_destroy(&ht);

weather = json_read(gdata,NULL, Weather);
stm_close(&gdata);


        /* Weather can be obtained from REST-API */
        if (weather != NULL)
        {
            if(weather->current_condition != NULL)
            {
                if(arrst_size(weather->current_condition,Condition) > 0)
                {
                    const Condition *condition = arrst_first_const(weather->current_condition, Condition);
                    const Values *weatherDesc2 = arrst_first_const(condition->weatherDesc, Values);
                       const Nearestarea *near = arrst_first_const(weather->nearest_area,Nearestarea);
                       const Country *counname = arrst_first_const(near->country, Country);

                    
app->lop = str_printf("\n City name : %s\n\n --------------- \n\n    pressure : %s \n  temp_C : %s \n  temp_F : %s \n weatherDesc: %s  \n Country : %s \n ---------------- ",app->count, tc(condition->pressure),tc(condition->temp_C),tc(condition->temp_F),tc(weatherDesc2->value),tc(counname->value));

                  
                }
               
            }
    
           
            
            dbind_destroy(&weather, Weather);
        }

return 0;

}
static void end_t(App *app,uint32_t rvalue)
{
if (rvalue == 0)
{
textview_printf(app->text,"%s\n",app->lop->data);
edit_text(app->country,"");
textview_scroll_down(app->text);
str_destroy(&app->lop);
}
}
static void bt(App *app,Event *e)
{
textview_clear(app->text);
app->count = edit_get_text(app->country);
osapp_task(app,0,i_OnButton,NULL,end_t,App);
unref(e);
}
static void ex(App *app,Event *e)
{
osapp_finish();
unref(app);
unref(e);

}
static Panel *i_panel(App *app)
{
Panel *panel = panel_create();
Layout *layout = layout_create(1, 5);
Label *desc = label_create();
Button *button = button_push();
Button *Exit = button_push();
TextView *text = textview_create();
app->country = edit_create();
app->text = text;
button_text(button, "Get Weather");
button_text(Exit, "Exit");
label_text(desc, "Enter Country or City Then Press Enter :");
button_OnClick(button, listener(app, bt, App));
button_OnClick(Exit, listener(app, ex, App));
textview_color(app->text, kCOLOR_GREEN);
textview_halign(app->text, ekCENTER);
textview_size(app->text, s2df(30.0, 30.0));
label_color(desc,kCOLOR_YELLOW);
layout_label(layout, desc, 0, 0);
layout_edit(layout, app->country, 0, 1);
layout_button(layout, button, 0, 2);
layout_button(layout, Exit, 0, 3);
layout_textview(layout, text, 0, 4);
layout_hsize(layout, 0, 250);
layout_vsize(layout, 4, 200);
layout_margin(layout, 5);
layout_vmargin(layout, 0, 5);
layout_vmargin(layout, 2, 5);
layout_vmargin(layout, 2, 5);
layout_vmargin(layout, 1, 5);
panel_layout(panel, layout);
init_bind();
return panel;
}

/---------------------------------------------------------------------------/

static void i_OnClose(App *app, Event *e)
{
bool_t *result = event_result(e, bool_t);
*result = FALSE;
bt(app,ekFOK);
unref(app);
unref(e);

}

/---------------------------------------------------------------------------/

static App *i_create(void)
{
App *app = heap_new0(App);
Panel *panel = i_panel(app);
app->window = window_create(ekWINDOW_TITLE | ekWINDOW_RETURN);
window_panel(app->window, panel);
window_title(app->window, "Weather info");
window_origin(app->window, v2df(500, 200));
window_OnClose(app->window, listener(app, i_OnClose, App));
window_show(app->window);
return app;
}

/---------------------------------------------------------------------------/

static void i_destroy(App **app)
{
window_destroy(&(*app)->window);
heap_delete(app, App);
}

/---------------------------------------------------------------------------/

#include "osmain.h"
osmain(i_create, i_destroy, "", App)

@lbhack
Copy link
Author

lbhack commented Jan 27, 2023

Screenshot 1401-11-07 at 18 56 01

@frang75
Copy link
Owner

frang75 commented Jan 28, 2023

Hi @lbhack !
That's looks good!
Congratulations on completing your first NAppGUI project.

@frang75
Copy link
Owner

frang75 commented Feb 7, 2023

@frang75 frang75 closed this as completed Feb 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

2 participants