Skip to main content

Get all current occurrence field in JSON

  • July 2, 2021
  • 9 replies
  • 0 views

JEAN-MARC SALIS
Forum|alt.badge.img

Hi everyone.


I'm pretty new to Uniface, so there's a good chance my question is basic, but I tried searching docs and Internet and didn't find the answer.

I also might mixed up correct terms between occurences, entities, etc.. sorry for that, I'll try to be understandable.


I've made a (web)service. In my component, I've painted needed entities et all.


For now, I've made several operations for retrieving datas from a web browser (using VueJS/Ajax). It works, cool.


I've worked mostly this way :

I use the GET parameters to filter the entity, I then loop all occurrencies

lineList = $newstruct
forentity "lf_lines"
    line = $newstruct
    line->$name = "%%no_order.lf_lines"
    line->qty = "%%qty.lf_lines"
    line->article = "%%artcode.lf_lines"
    line->noline = "%%no_line.lf_lines"
    lineList->*{-1} = line
endfor

And then convert my struct to json and send it back with $webinfo("OUTPUT")


For the operation I'm currently working on, I need to get all the field of the entity occurence. That means around 40 fields (for reasons...).

I know for sure I will only have one answer (or zero) because my GET parameters are the primary key.


Is there a way to avoid declare all the field one by one ? Something like converting my answer to JSON (or to struct then to JSON) ?


Thanks in advance for your answers, and don't hesitate to ask me if I'm not clear !


Regards,

JM

9 replies

Iain Sharp
Forum|alt.badge.img+5
  • Inspiring
  • July 2, 2021

Hi everyone.


I'm pretty new to Uniface, so there's a good chance my question is basic, but I tried searching docs and Internet and didn't find the answer.

I also might mixed up correct terms between occurences, entities, etc.. sorry for that, I'll try to be understandable.


I've made a (web)service. In my component, I've painted needed entities et all.


For now, I've made several operations for retrieving datas from a web browser (using VueJS/Ajax). It works, cool.


I've worked mostly this way :

I use the GET parameters to filter the entity, I then loop all occurrencies

lineList = $newstruct
forentity "lf_lines"
    line = $newstruct
    line->$name = "%%no_order.lf_lines"
    line->qty = "%%qty.lf_lines"
    line->article = "%%artcode.lf_lines"
    line->noline = "%%no_line.lf_lines"
    lineList->*{-1} = line
endfor

And then convert my struct to json and send it back with $webinfo("OUTPUT")


For the operation I'm currently working on, I need to get all the field of the entity occurence. That means around 40 fields (for reasons...).

I know for sure I will only have one answer (or zero) because my GET parameters are the primary key.


Is there a way to avoid declare all the field one by one ? Something like converting my answer to JSON (or to struct then to JSON) ?


Thanks in advance for your answers, and don't hesitate to ask me if I'm not clear !


Regards,

JM

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain


JEAN-MARC SALIS
Forum|alt.badge.img
  • Author
  • Participating Frequently
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

I only get a part of the fields (25) doing that, in a node (named OCC)


I checked if I can access other fields by doing a


v_struct->otherfield = "%%other_field.ENTITYNAME"


I do that AFTER the componenttostruct.


And then, I have it in the JSON after the occ node AND in the occnode ! Which is now 26 fields.


I've tried other fields, and it has the same behavior. i tried 2, had 27 fields, etc...


Maybe there's a limit of 25 field by default ?


The doc says "Static fields are skipped", but I checked and the missing fields are not static (and it says nothing about a 25 limit)


Strange.


JM


Iain Sharp
Forum|alt.badge.img+5
  • Inspiring
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

WHat is your fieldlist set to (in define structure, for the entity). If it's Blank (automatic) it will only have fields specifically mentioned in the code (anywhere in the code) in the field list. 

You can set it to 'all fields' ( * ) and it should include all the fields in the component. 


David Akerman
Forum|alt.badge.img

Hi everyone.


I'm pretty new to Uniface, so there's a good chance my question is basic, but I tried searching docs and Internet and didn't find the answer.

I also might mixed up correct terms between occurences, entities, etc.. sorry for that, I'll try to be understandable.


I've made a (web)service. In my component, I've painted needed entities et all.


For now, I've made several operations for retrieving datas from a web browser (using VueJS/Ajax). It works, cool.


I've worked mostly this way :

I use the GET parameters to filter the entity, I then loop all occurrencies

lineList = $newstruct
forentity "lf_lines"
    line = $newstruct
    line->$name = "%%no_order.lf_lines"
    line->qty = "%%qty.lf_lines"
    line->article = "%%artcode.lf_lines"
    line->noline = "%%no_line.lf_lines"
    lineList->*{-1} = line
endfor

And then convert my struct to json and send it back with $webinfo("OUTPUT")


For the operation I'm currently working on, I need to get all the field of the entity occurence. That means around 40 fields (for reasons...).

I know for sure I will only have one answer (or zero) because my GET parameters are the primary key.


Is there a way to avoid declare all the field one by one ? Something like converting my answer to JSON (or to struct then to JSON) ?


Thanks in advance for your answers, and don't hesitate to ask me if I'm not clear !


Regards,

JM

Hi Jean-Marc,

What is your use case? Are you trying to create a REST service that includes update functionality, or just return data in JSON format?

I assume you're looping through occurrences in your code to support any number or matching return occurrences, e.g. a full set or of records, or 0/1 occurrences if the URL contains an ID (which is the case I assume you're referring to).

In either case, instead I would use componentToStruct specifying an entity name to create all retrieved occurrences and fields instead of looping through occurrences, e.g.

componentToStruct vStruct, vEntity

Edit: I see Iain already suggested this by the time I posted my response, but see below for some more information.

You can use the /reconnectTags switch to include some extra information about modification status if you want to use Uniface's inbuilt disconnected record set functionality with updates, but that would need additional changes for JSON usage, so i'll try and keep it simple here.

I would then manipulate the struct to remove the "OCC" tags so it looks more like a normal JSON array, e.g.

vStruct->OCC->$name = ""

Finally I'd use structToJSON to convert the struct to JSON.

I'd also set the response type in HTTP response headers (including others for access control), e.g.

putitem/id $webinfo("HTTPRESPONSEHEADERS"),"Content-Type", "application/json"

Regards,
David



JEAN-MARC SALIS
Forum|alt.badge.img
  • Author
  • Participating Frequently
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

Thanks again for your time Iain.


I don't see the fieldlist property in the define structure (I'm using Uniface 10.3).


I have Name, Inherits, Type, Description, Database Behavior, Database Access, Database Path and Database Interface in the main window.


There are more in the Object tab on the right, but no fieldset.


Again, I know I am totally newbie and it's probably in plain sight, so sorry if I waste your time for trivial info.


JM


Iain Sharp
Forum|alt.badge.img+5
  • Inspiring
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

Hi, 

In the define structure tab, with the entity selected, You should see an entry on the right labelled fieldlist in the section "Database I/O" as per below. 

Blank entry  = automatic (only fields directly referenced in code or relationships.

asterisk =  All ( as per below)

list of fields = restrict to this list of fields. 

It should give a ... to take you to a form to select the field list



JEAN-MARC SALIS
Forum|alt.badge.img
  • Author
  • Participating Frequently
  • July 2, 2021

Hi Jean-Marc,

What is your use case? Are you trying to create a REST service that includes update functionality, or just return data in JSON format?

I assume you're looping through occurrences in your code to support any number or matching return occurrences, e.g. a full set or of records, or 0/1 occurrences if the URL contains an ID (which is the case I assume you're referring to).

In either case, instead I would use componentToStruct specifying an entity name to create all retrieved occurrences and fields instead of looping through occurrences, e.g.

componentToStruct vStruct, vEntity

Edit: I see Iain already suggested this by the time I posted my response, but see below for some more information.

You can use the /reconnectTags switch to include some extra information about modification status if you want to use Uniface's inbuilt disconnected record set functionality with updates, but that would need additional changes for JSON usage, so i'll try and keep it simple here.

I would then manipulate the struct to remove the "OCC" tags so it looks more like a normal JSON array, e.g.

vStruct->OCC->$name = ""

Finally I'd use structToJSON to convert the struct to JSON.

I'd also set the response type in HTTP response headers (including others for access control), e.g.

putitem/id $webinfo("HTTPRESPONSEHEADERS"),"Content-Type", "application/json"

Regards,
David


Thanks David for your answer. this is indeed the way to do it, but I've got more pbs that we are currently discussing with Iain in the comments of his answer.


But again, thanks for your time and your answer !


(to answer your first question, it's not a REST service but could have. It's an inside project, and I started with GET parameters for read or write, managing the routeur on the JS side, so I'll stick to that for now. I manage eventual locks on datas by returning the info on the browser side of the App to avoid conflict. So far it works as expected 🙂. I'm sure there are Uniface way to do it better than I do, but I just start Uniface).


Iain Sharp
Forum|alt.badge.img+5
  • Inspiring
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

Unless your entity is not-modeled (dummy) in which case the field list is set to 'all' anyway, as all the fields are declared local to the component. 


JEAN-MARC SALIS
Forum|alt.badge.img
  • Author
  • Participating Frequently
  • July 2, 2021

The struct MAY need some playing with afterwards but I think you'll get somewhere with :-

componenttostruct v_struct,"YOURENTITYNAME"

This should put all fields of yourentityname into one node per occurrence (so, one node), but you might want to re-name that node to make nice json.... 


Iain

Ok, I thought it was on the definition of the entity (where it's not)


But I found it in the entity on my component and now it works


Thank you very much again Iain !!


I can go on now !


JM