问:
JSONObject().put using a List Throws recursivelyDefinedObjectException
I have a query that generates a List of Tickets using hibernate like so :

```<code>Query query = session.createQuery(
        "SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone  FROM Ticket T, User U, Logiciel L, Version V "
        + "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
        .setParameter("user", user);
</code>```

I tried to put the list in a JSONObject :

```<code>    List allTickets = ticketDao.getTicketsByUserDao(user);
    JSONObject jo = new JSONObject();
    jo.put("ticket", allTickets);
</code>```

It throws this exception :

```<code>Hibernate: select ticket0_.ticket_id as col_0_0_, ticket0_.objet as col_1_0_, ticket0_.details as col_2_0_, ticket0_.etat as col_3_0_, ticket0_.severity as col_4_0_, ticket0_.createDateTime as col_5_0_, ticket0_.user_id as col_6_0_, ticket0_.attachment_path as col_7_0_, user1_.last_name as col_8_0_, logiciel2_.nom_logiciel as col_9_0_, version3_.nom_version as col_10_0_, ticket0_.assigned_to as col_11_0_, ticket0_.closed_by as col_12_0_, ticket0_.closedDateTime as col_13_0_, ticket0_.assignedDateTime as col_14_0_, user1_.first_name as col_15_0_, user1_.username as col_16_0_, user1_.email as col_17_0_, user1_.phone as col_18_0_, user4_.user_id as user_id1_9_, user4_.email as email2_9_, user4_.etat as etat3_9_, user4_.phone as phone4_9_, user4_.currentAccessDate as currenta5_9_, user4_.dateExpiration as dateexpi6_9_, user4_.first_name as first_na7_9_, user4_.lastAccessDate as lastacce8_9_, user4_.last_name as last_nam9_9_, user4_.password as passwor10_9_, user4_.structure_id as structu12_9_, user4_.username as usernam11_9_ from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' order by ticket0_.createDateTime
Hibernate: select tickets0_.user_id as user_id14_8_2_, tickets0_.ticket_id as ticket_i1_8_2_, tickets0_.ticket_id as ticket_i1_8_1_, tickets0_.assigned_to as assigned2_8_1_, tickets0_.attachment_path as attachme3_8_1_, tickets0_.closed_by as closed_b4_8_1_, tickets0_.details as details5_8_1_, tickets0_.etat as etat6_8_1_, tickets0_.logiciel_id as logiciel7_8_1_, tickets0_.objet as objet8_8_1_, tickets0_.severity as severity9_8_1_, tickets0_.version_id as version10_8_1_, tickets0_.assignedDateTime as assigne11_8_1_, tickets0_.closedDateTime as closedd12_8_1_, tickets0_.createDateTime as created13_8_1_, tickets0_.user_id as user_id14_8_1_, planificat1_.planif_id as planif_i1_4_0_, planificat1_.observation as observat2_4_0_, planificat1_.date_debut_planif as date_deb3_4_0_, planificat1_.date_debut_realise as date_deb4_4_0_, planificat1_.date_fin_planif as date_fin5_4_0_, planificat1_.date_fin_realise as date_fin6_4_0_, planificat1_.ticket_id as ticket_i7_4_0_ from tickets tickets0_ left outer join planification planificat1_ on tickets0_.ticket_id=planificat1_.ticket_id where tickets0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select responses0_.user_id as user_id5_5_4_, responses0_.response_id as response1_5_4_, responses0_.response_id as response1_5_3_, responses0_.response as response2_5_3_, responses0_.createDateTime as createda3_5_3_, responses0_.ticket_id as ticket_i4_5_3_, responses0_.user_id as user_id5_5_3_, ticket1_.ticket_id as ticket_i1_8_0_, ticket1_.assigned_to as assigned2_8_0_, ticket1_.attachment_path as attachme3_8_0_, ticket1_.closed_by as closed_b4_8_0_, ticket1_.details as details5_8_0_, ticket1_.etat as etat6_8_0_, ticket1_.logiciel_id as logiciel7_8_0_, ticket1_.objet as objet8_8_0_, ticket1_.severity as severity9_8_0_, ticket1_.version_id as version10_8_0_, ticket1_.assignedDateTime as assigne11_8_0_, ticket1_.closedDateTime as closedd12_8_0_, ticket1_.createDateTime as created13_8_0_, ticket1_.user_id as user_id14_8_0_, user2_.user_id as user_id1_9_1_, user2_.email as email2_9_1_, user2_.etat as etat3_9_1_, user2_.phone as phone4_9_1_, user2_.currentAccessDate as currenta5_9_1_, user2_.dateExpiration as dateexpi6_9_1_, user2_.first_name as first_na7_9_1_, user2_.lastAccessDate as lastacce8_9_1_, user2_.last_name as last_nam9_9_1_, user2_.password as passwor10_9_1_, user2_.structure_id as structu12_9_1_, user2_.username as usernam11_9_1_, planificat3_.planif_id as planif_i1_4_2_, planificat3_.observation as observat2_4_2_, planificat3_.date_debut_planif as date_deb3_4_2_, planificat3_.date_debut_realise as date_deb4_4_2_, planificat3_.date_fin_planif as date_fin5_4_2_, planificat3_.date_fin_realise as date_fin6_4_2_, planificat3_.ticket_id as ticket_i7_4_2_ from responses responses0_ inner join tickets ticket1_ on responses0_.ticket_id=ticket1_.ticket_id left outer join users user2_ on ticket1_.user_id=user2_.user_id left outer join planification planificat3_ on ticket1_.ticket_id=planificat3_.ticket_id where responses0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
org.json.JSONException: JavaBean object contains recursively defined member variable of key "planification"
    at org.json.JSONObject.recursivelyDefinedObjectException(JSONObject.java:2722)
    at org.json.JSONObject.populateMap(JSONObject.java:1558)
    at org.json.JSONObject.<init>(JSONObject.java:372)
    at org.json.JSONObject.wrap(JSONObject.java:2496)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.<init>(JSONObject.java:372)
    at org.json.JSONObject.wrap(JSONObject.java:2496)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.populateMap(JSONObject.java:1530)
    at org.json.JSONObject.<init>(JSONObject.java:367)
    at org.json.JSONObject.wrap(JSONObject.java:2499)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1609)
    at org.json.JSONArray.<init>(JSONArray.java:176)
    at org.json.JSONObject.wrap(JSONObject.java:2478)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.populateMap(JSONObject.java:1530)
    at org.json.JSONObject.<init>(JSONObject.java:367)
    at org.json.JSONObject.wrap(JSONObject.java:2499)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1661)
    at org.json.JSONArray.<init>(JSONArray.java:228)
    at org.json.JSONObject.wrap(JSONObject.java:2481)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1609)
    at org.json.JSONArray.<init>(JSONArray.java:176)
    at org.json.JSONObject.put(JSONObject.java:1771)
    at com.myproject.helpdesk.controllers.TicketManagement.getTicketsByUser(TicketManagement.java:610)
    at com.myproject.helpdesk.controllers.TicketManagement.doGet(TicketManagement.java:95)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.myproject.helpdesk.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:33)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:366)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:847)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1680)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)
</code>```

What is a recursivelyDefinedObjectException ? my Google searches always lead to the subject of Recursion &  Functions, not the exception.

When debugging, the allTickets List contains 4 objects like so :

```<code>[
 [Ljava.lang.Object;@10e63606,
 [Ljava.lang.Object;@3c76d000,
 [Ljava.lang.Object;@5f5bfd07,
 [Ljava.lang.Object;@3a14ab96
]
</code>```

He's the content of one first object for example :

```<code>[1455, test ticket, hello world, créé, Critique, 2022-02-03T15:48:41.058086, com.myproject.helpdesk.models.User@6f643c88, null, CTH, dummy, 10.1.1.v, null, null, 2022-02-03T15:48:41.058086, 2022-02-03T15:48:41.058086, CTH, CTH, email@something.com, 00999999999]
</code>```

Environment :

Eclipse : Version: 2021-06 (4.20.0) Build id: 20210612-2011

Java 8

my JSONOject comes from this dependency

Any help appreciated.

EDIT: Adding Entities

Fetching the Tickets list is what's causing the problem so .

Ticket

```<code>@Entity
@Table(name = "tickets")
public class Ticket implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ticket_id")
    private int ticket_id;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false, insertable = true)
    private User user;

    @OneToMany(fetch = FetchType.EAGER,mappedBy="ticket")
    private List<Response> response;

     @OneToOne(mappedBy = "ticket")
     private Planification planification;
</code>```

Planification

```<code>@Entity
@Table(name = "planification")
public class Planification implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "planif_id")
    private int planifId;

    @OneToOne
    @JoinColumn(name = "ticket_id",unique = true)
    private Ticket ticket;
</code>```

User

```<code>@Entity
@Table(name = "users")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private int user_id;

    @OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Ticket> tickets;

    @OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Response> responses;

    @ManyToOne(fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
    @JoinColumn(name = "structure_id")
    private Structure structure;
</code>```

Response

```<code>@Entity
@Table(name = "responses")
public class Response implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "response_id")
    private int responseId;

    @ManyToOne
    @JoinColumn(name = "ticket_id", nullable = false, insertable = true)
    private Ticket ticket;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false, insertable = true)
    private User user;
</code>```

Structure

```<code>@Entity
@Table(name = "structure")
public class Structure implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "structure_id")
    private int structure_id;

    @OneToMany(mappedBy = "structure")
    private List<User> user;
</code>```

EDIT 2 :

When debugging I noticed that aStructure of User's Ticket has exception stack trace as content for it's PersistentBag,

What the hell is causing this ?! I checked my Entity definitions and they look alright to me.

Side note

My Ticket object contains the User object, which contains a list of the Users's Tickets, and it goes on and on forever, infinite recursion, is this normal ? are my Entity definitions wrong ? how can i fix this ?

答:
I see you managed to fix it, but i'll add another option for completeness. I managed to recreate your exact exception with two simple classes, whose instances form a circular refference, as in your case.

User:

```<code>public class User {

    private long id;
    private Ticket ticket;

    public User(long id) {
        this.id = id;
    }

    //getters and setters
}
</code>```

Ticket

```<code>public class Ticket {

    private long id;
    private User user;

    public Ticket(long id) {
        this.id = id;
    }

    //getters and setters
}
</code>```

The setup:

```<code>User user = new User(1);
Ticket ticket = new Ticket(2);
user.setTicket(ticket);
ticket.setUser(user);
List<User> users = Arrays.asList(user, user, user);
</code>```

The instances refference each other into infinity, as in your case. That's totally valid in java, but it's hard to represent in json. According to my tests directly adding the collection, causes Exception in thread "main" org.json.JSONException: JavaBean object contains recursively defined member variable of key "ticket".

```<code>JSONObject jsonObject = new JSONObject();
jsonObject.put("users", users);
System.out.println(jsonObject);
</code>```

jsonObject.put(key, collection) creates json array from the collection, but for some reason can't deal with circular refferences in collection elements.

The workaround, which fixed it, was to manually create JSONArray, then iterate the collection adding each element manually JSONArray. Then add the prepared json array in JSONObject.

```<code>JSONArray jsonArray = new JSONArray();
users.forEach(jsonArray::put);
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", jsonArray);
System.out.println(jsonObject);
</code>```

Body:
I have a query that generates a List of Tickets using hibernate like so :

Query query = session.createQuery(
        "SELECT T.id, T.Objet, T.Details, T.Etat,T.Severity, T.createDateTime, T.user, T.Attachment, U.lastName, L.nomLogiciel, V.nomVersion,T.AssignedTo,T.ClosedBy,T.closedDateTime,T.assignedDateTime, U.firstName, U.username, U.Email, U.Phone  FROM Ticket T, User U, Logiciel L, Version V "
        + "WHERE T.user= :user and T.user=U.user_id AND L.logiciel_id=T.Logiciel AND T.Version=V.version_id AND T.Etat!='fermer' ORDER BY T.createDateTime ")
        .setParameter("user", user);

I tried to put the list in a JSONObject :

    List allTickets = ticketDao.getTicketsByUserDao(user);
    JSONObject jo = new JSONObject();
    jo.put("ticket", allTickets);

It throws this exception :

Hibernate: select ticket0_.ticket_id as col_0_0_, ticket0_.objet as col_1_0_, ticket0_.details as col_2_0_, ticket0_.etat as col_3_0_, ticket0_.severity as col_4_0_, ticket0_.createDateTime as col_5_0_, ticket0_.user_id as col_6_0_, ticket0_.attachment_path as col_7_0_, user1_.last_name as col_8_0_, logiciel2_.nom_logiciel as col_9_0_, version3_.nom_version as col_10_0_, ticket0_.assigned_to as col_11_0_, ticket0_.closed_by as col_12_0_, ticket0_.closedDateTime as col_13_0_, ticket0_.assignedDateTime as col_14_0_, user1_.first_name as col_15_0_, user1_.username as col_16_0_, user1_.email as col_17_0_, user1_.phone as col_18_0_, user4_.user_id as user_id1_9_, user4_.email as email2_9_, user4_.etat as etat3_9_, user4_.phone as phone4_9_, user4_.currentAccessDate as currenta5_9_, user4_.dateExpiration as dateexpi6_9_, user4_.first_name as first_na7_9_, user4_.lastAccessDate as lastacce8_9_, user4_.last_name as last_nam9_9_, user4_.password as passwor10_9_, user4_.structure_id as structu12_9_, user4_.username as usernam11_9_ from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' order by ticket0_.createDateTime
Hibernate: select tickets0_.user_id as user_id14_8_2_, tickets0_.ticket_id as ticket_i1_8_2_, tickets0_.ticket_id as ticket_i1_8_1_, tickets0_.assigned_to as assigned2_8_1_, tickets0_.attachment_path as attachme3_8_1_, tickets0_.closed_by as closed_b4_8_1_, tickets0_.details as details5_8_1_, tickets0_.etat as etat6_8_1_, tickets0_.logiciel_id as logiciel7_8_1_, tickets0_.objet as objet8_8_1_, tickets0_.severity as severity9_8_1_, tickets0_.version_id as version10_8_1_, tickets0_.assignedDateTime as assigne11_8_1_, tickets0_.closedDateTime as closedd12_8_1_, tickets0_.createDateTime as created13_8_1_, tickets0_.user_id as user_id14_8_1_, planificat1_.planif_id as planif_i1_4_0_, planificat1_.observation as observat2_4_0_, planificat1_.date_debut_planif as date_deb3_4_0_, planificat1_.date_debut_realise as date_deb4_4_0_, planificat1_.date_fin_planif as date_fin5_4_0_, planificat1_.date_fin_realise as date_fin6_4_0_, planificat1_.ticket_id as ticket_i7_4_0_ from tickets tickets0_ left outer join planification planificat1_ on tickets0_.ticket_id=planificat1_.ticket_id where tickets0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select response0_.ticket_id as ticket_i4_5_0_, response0_.response_id as response1_5_0_, response0_.response_id as response1_5_1_, response0_.response as response2_5_1_, response0_.createDateTime as createda3_5_1_, response0_.ticket_id as ticket_i4_5_1_, response0_.user_id as user_id5_5_1_, user1_.user_id as user_id1_9_2_, user1_.email as email2_9_2_, user1_.etat as etat3_9_2_, user1_.phone as phone4_9_2_, user1_.currentAccessDate as currenta5_9_2_, user1_.dateExpiration as dateexpi6_9_2_, user1_.first_name as first_na7_9_2_, user1_.lastAccessDate as lastacce8_9_2_, user1_.last_name as last_nam9_9_2_, user1_.password as passwor10_9_2_, user1_.structure_id as structu12_9_2_, user1_.username as usernam11_9_2_, structure2_.structure_id as structur1_6_3_, structure2_.nom_structure as nom_stru2_6_3_ from responses response0_ inner join users user1_ on response0_.user_id=user1_.user_id left outer join structure structure2_ on user1_.structure_id=structure2_.structure_id where response0_.ticket_id=?
Hibernate: select responses0_.user_id as user_id5_5_4_, responses0_.response_id as response1_5_4_, responses0_.response_id as response1_5_3_, responses0_.response as response2_5_3_, responses0_.createDateTime as createda3_5_3_, responses0_.ticket_id as ticket_i4_5_3_, responses0_.user_id as user_id5_5_3_, ticket1_.ticket_id as ticket_i1_8_0_, ticket1_.assigned_to as assigned2_8_0_, ticket1_.attachment_path as attachme3_8_0_, ticket1_.closed_by as closed_b4_8_0_, ticket1_.details as details5_8_0_, ticket1_.etat as etat6_8_0_, ticket1_.logiciel_id as logiciel7_8_0_, ticket1_.objet as objet8_8_0_, ticket1_.severity as severity9_8_0_, ticket1_.version_id as version10_8_0_, ticket1_.assignedDateTime as assigne11_8_0_, ticket1_.closedDateTime as closedd12_8_0_, ticket1_.createDateTime as created13_8_0_, ticket1_.user_id as user_id14_8_0_, user2_.user_id as user_id1_9_1_, user2_.email as email2_9_1_, user2_.etat as etat3_9_1_, user2_.phone as phone4_9_1_, user2_.currentAccessDate as currenta5_9_1_, user2_.dateExpiration as dateexpi6_9_1_, user2_.first_name as first_na7_9_1_, user2_.lastAccessDate as lastacce8_9_1_, user2_.last_name as last_nam9_9_1_, user2_.password as passwor10_9_1_, user2_.structure_id as structu12_9_1_, user2_.username as usernam11_9_1_, planificat3_.planif_id as planif_i1_4_2_, planificat3_.observation as observat2_4_2_, planificat3_.date_debut_planif as date_deb3_4_2_, planificat3_.date_debut_realise as date_deb4_4_2_, planificat3_.date_fin_planif as date_fin5_4_2_, planificat3_.date_fin_realise as date_fin6_4_2_, planificat3_.ticket_id as ticket_i7_4_2_ from responses responses0_ inner join tickets ticket1_ on responses0_.ticket_id=ticket1_.ticket_id left outer join users user2_ on ticket1_.user_id=user2_.user_id left outer join planification planificat3_ on ticket1_.ticket_id=planificat3_.ticket_id where responses0_.user_id in (select user4_.user_id from tickets ticket0_ cross join users user1_ cross join logiciel logiciel2_ cross join version version3_ inner join users user4_ on ticket0_.user_id=user4_.user_id where ticket0_.user_id=? and ticket0_.user_id=user1_.user_id and logiciel2_.logiciel_id=ticket0_.logiciel_id and ticket0_.version_id=version3_.version_id and ticket0_.etat<>'fermer' )
org.json.JSONException: JavaBean object contains recursively defined member variable of key "planification"
    at org.json.JSONObject.recursivelyDefinedObjectException(JSONObject.java:2722)
    at org.json.JSONObject.populateMap(JSONObject.java:1558)
    at org.json.JSONObject.<init>(JSONObject.java:372)
    at org.json.JSONObject.wrap(JSONObject.java:2496)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.<init>(JSONObject.java:372)
    at org.json.JSONObject.wrap(JSONObject.java:2496)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.populateMap(JSONObject.java:1530)
    at org.json.JSONObject.<init>(JSONObject.java:367)
    at org.json.JSONObject.wrap(JSONObject.java:2499)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1609)
    at org.json.JSONArray.<init>(JSONArray.java:176)
    at org.json.JSONObject.wrap(JSONObject.java:2478)
    at org.json.JSONObject.populateMap(JSONObject.java:1563)
    at org.json.JSONObject.populateMap(JSONObject.java:1530)
    at org.json.JSONObject.<init>(JSONObject.java:367)
    at org.json.JSONObject.wrap(JSONObject.java:2499)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1661)
    at org.json.JSONArray.<init>(JSONArray.java:228)
    at org.json.JSONObject.wrap(JSONObject.java:2481)
    at org.json.JSONObject.wrap(JSONObject.java:2457)
    at org.json.JSONArray.addAll(JSONArray.java:1609)
    at org.json.JSONArray.<init>(JSONArray.java:176)
    at org.json.JSONObject.put(JSONObject.java:1771)
    at com.myproject.helpdesk.controllers.TicketManagement.getTicketsByUser(TicketManagement.java:610)
    at com.myproject.helpdesk.controllers.TicketManagement.doGet(TicketManagement.java:95)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:655)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:764)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at com.myproject.helpdesk.util.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:33)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:196)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:542)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:135)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:366)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:639)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:847)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1680)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:748)

What is a recursivelyDefinedObjectException ? my Google searches always lead to the subject of Recursion &  Functions, not the exception.

When debugging, the allTickets List contains 4 objects like so :

[
 [Ljava.lang.Object;@10e63606,
 [Ljava.lang.Object;@3c76d000,
 [Ljava.lang.Object;@5f5bfd07,
 [Ljava.lang.Object;@3a14ab96
]

He's the content of one first object for example :

[1455, test ticket, hello world, créé, Critique, 2022-02-03T15:48:41.058086, com.myproject.helpdesk.models.User@6f643c88, null, CTH, dummy, 10.1.1.v, null, null, 2022-02-03T15:48:41.058086, 2022-02-03T15:48:41.058086, CTH, CTH, email@something.com, 00999999999]

Environment :

Eclipse : Version: 2021-06 (4.20.0) Build id: 20210612-2011

Java 8

my JSONOject comes from this dependency

Any help appreciated.

EDIT: Adding Entities

Fetching the Tickets list is what's causing the problem so .

Ticket

@Entity
@Table(name = "tickets")
public class Ticket implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ticket_id")
    private int ticket_id;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false, insertable = true)
    private User user;

    @OneToMany(fetch = FetchType.EAGER,mappedBy="ticket")
    private List<Response> response;

     @OneToOne(mappedBy = "ticket")
     private Planification planification;

Planification

@Entity
@Table(name = "planification")
public class Planification implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "planif_id")
    private int planifId;

    @OneToOne
    @JoinColumn(name = "ticket_id",unique = true)
    private Ticket ticket;

User

@Entity
@Table(name = "users")
public class User implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "user_id")
    private int user_id;

    @OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Ticket> tickets;

    @OneToMany(fetch = FetchType.EAGER ,mappedBy="user")
    @Fetch(value = FetchMode.SUBSELECT)
    private List<Response> responses;

    @ManyToOne(fetch = FetchType.EAGER ,cascade = CascadeType.ALL)
    @JoinColumn(name = "structure_id")
    private Structure structure;

Response

@Entity
@Table(name = "responses")
public class Response implements Serializable{

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "response_id")
    private int responseId;

    @ManyToOne
    @JoinColumn(name = "ticket_id", nullable = false, insertable = true)
    private Ticket ticket;

    @ManyToOne
    @JoinColumn(name = "user_id", nullable = false, insertable = true)
    private User user;

Structure

@Entity
@Table(name = "structure")
public class Structure implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "structure_id")
    private int structure_id;

    @OneToMany(mappedBy = "structure")
    private List<User> user;

EDIT 2 :

When debugging I noticed that aStructure of User's Ticket has exception stack trace as content for it's PersistentBag,

What the hell is causing this ?! I checked my Entity definitions and they look alright to me.

Side note

My Ticket object contains the User object, which contains a list of the Users's Tickets, and it goes on and on forever, infinite recursion, is this normal ? are my Entity definitions wrong ? how can i fix this ?

Body:
I see you managed to fix it, but i'll add another option for completeness. I managed to recreate your exact exception with two simple classes, whose instances form a circular refference, as in your case.

User:

public class User {

    private long id;
    private Ticket ticket;

    public User(long id) {
        this.id = id;
    }

    //getters and setters
}

Ticket

public class Ticket {

    private long id;
    private User user;

    public Ticket(long id) {
        this.id = id;
    }

    //getters and setters
}

The setup:

User user = new User(1);
Ticket ticket = new Ticket(2);
user.setTicket(ticket);
ticket.setUser(user);
List<User> users = Arrays.asList(user, user, user);

The instances refference each other into infinity, as in your case. That's totally valid in java, but it's hard to represent in json. According to my tests directly adding the collection, causes Exception in thread "main" org.json.JSONException: JavaBean object contains recursively defined member variable of key "ticket".

JSONObject jsonObject = new JSONObject();
jsonObject.put("users", users);
System.out.println(jsonObject);

jsonObject.put(key, collection) creates json array from the collection, but for some reason can't deal with circular refferences in collection elements.

The workaround, which fixed it, was to manually create JSONArray, then iterate the collection adding each element manually JSONArray. Then add the prepared json array in JSONObject.

JSONArray jsonArray = new JSONArray();
users.forEach(jsonArray::put);
JSONObject jsonObject = new JSONObject();
jsonObject.put("users", jsonArray);
System.out.println(jsonObject);


来源: stackexchange

问:
Cannot read properties of null (reading 'id')
I am attempting to use a form to send data to a table in a MySQL database.
When clicking on the create button, I receive this error in the chrome dev console only.

I have configured this application by combining Jason Watmore's Front-end and Back-end code and updated the project to Angular version 11 with VS code terminal commands.
https://jasonwatmore.com/post/2020/08/29/angular-10-boilerplate-email-sign-up-with-verification-authentication-forgot-password

AND

https://jasonwatmore.com/post/2020/09/08/nodejs-mysql-boilerplate-api-with-email-sign-up-verification-authentication-forgot-password

All other aspects of the project are working as expected since I have not edited those. (registration, verification, login, update profile data from other MySQL table etc.)

My DB Table is called 'lab-swaps' with these properties.

Any assistance or guidance is very much appreciated, I hope this question includes enough detail.
Thank you for reading.

Front-End Code

home.component.html:

Welcome {{account.firstName}}!

You can create a lab swap request here!

<form [formGroup]="labSwapForm" (ngSubmit)="onSubmit()">

        Your Full Name
        <input type="text" formControlName="swapCandidateOne" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.swapCandidateOne.errors }" />

Full Name is required

        Lab Swap Request Details
        <input type="text" formControlName="swapRequestDetail" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.swapRequestDetail.errors }" />

Lab Swap Details are required

        <button type="submit" [disabled]="loading" class="btn btn-primary mr-2 mb-3 ml-3">

            Create Lab Swap Request
        </button>

</form>```
</div>
</div>
</p>
<p>home.component.ts:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { AccountService, AlertService, LabSwapService } from '@app/_services';
import { first } from 'rxjs/operators';

@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
    account = this.accountService.accountValue;
    labSwap = this.labSwapService.labSwapValue;
    loading = false;
    submitted = false;
    labSwapForm: FormGroup;

    constructor(
        private accountService: AccountService,
        private labSwapService: LabSwapService,
        private formBuilder: FormBuilder,
        private router: Router,
        private alertService: AlertService,
        private route: ActivatedRoute,
    ) { }

    ngOnInit() {
        this.labSwapForm = this.formBuilder.group({
            //id: this.formBuilder.control(null, Validators.required),
            swapCandidateOne: this.formBuilder.control(null),
            swapRequestDetail: this.formBuilder.control(null)
            // swapCandidateOne: [this.labSwap.swapCandidateOne, Validators.required],
            // swapRequestDetail: [this.labSwap.swapRequestDetail, Validators.required],
        });
    }

    get f() {
        return this.labSwapForm.controls;
    }

    onSubmit() {
        debugger;

        // reset alerts on submit
        //this.alertService.clear();

        // stop here if form is invalid
        if (this.labSwapForm.invalid) {
            return;
        }

        this.loading = true;
        this.labSwapService.update(this.labSwap.id, this.labSwapForm.value) //id is the issue here!
            .pipe(first())
            .subscribe({
                next: () => {
                    this.alertService.success('Lab Swap Created successfully', { keepAfterRouteChange: true });
                    this.router.navigate(['../'], { relativeTo: this.route });
                },
                error: error => {
                    this.alertService.error(error);
                    this.loading = false;
                }
            });
        debugger;
    }
}</code>```

labSwap.ts (model):

export class LabSwap {
    id: number;
    fullNameList: string;
    swapRequestDetail: string;
    swapCandidateOne: string;
    swapCandidateTwo: string;
    isSwapComplete: boolean;

}```
</div>
</div>
</p>
<p>lab-swap.service.ts:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, finalize } from 'rxjs/operators';

import { environment } from '@environments/environment';
import { LabSwap } from '@app/_models';

//const baseUrl = `${environment.apiUrl}/accounts`;
const baseUrl = `${environment.apiUrl}/lab-swap`;
//const baseUrl = `${environment.apiUrl}/home`;

@Injectable({ providedIn: 'root' })
export class LabSwapService {
    private labSwapSubject: BehaviorSubject<LabSwap>;
    public labSwap: Observable<LabSwap>;

    constructor(
        private router: Router,
        private http: HttpClient
    ) {
        this.labSwapSubject = new BehaviorSubject<LabSwap>(null);
        this.labSwap = this.labSwapSubject.asObservable();
    }

    public get labSwapValue(): LabSwap {
        return this.labSwapSubject.value;
    }

    logout() {
        this.http.post<any>(`${baseUrl}/revoke-token`, {}, { withCredentials: true }).subscribe();
        this.stopRefreshTokenTimer();
        this.labSwapSubject.next(null);
        this.router.navigate(['/account/login']);
    }

    getAll() {
        return this.http.get<LabSwap[]>(baseUrl);
    }

    getById(id: string) {
        return this.http.get<LabSwap>(`${baseUrl}/${id}`);
    }

    create(params) {
        return this.http.post(baseUrl, params);
    }

    update(id, params) {
        return this.http.put(`${baseUrl}/${id}`, params)
            .pipe(map((labSwap: any) => {
                // update the current lab swap if it was updated
                if (labSwap.id === this.labSwapValue.id) {
                    // publish updated lab swap to subscribers
                    labSwap = { ...this.labSwapValue, ...labSwap };
                    this.labSwapSubject.next(labSwap);
                }
                return labSwap;
            }));
    }

}</code>```

Back-End Code

lab-swap.controller.js:

const express = require('express');
const router = express.Router();
const Joi = require('joi');
const validateRequest = require('_middleware/validate-request');
const authorize = require('_middleware/authorize')
const Role = require('_helpers/role');
const accountService = require('./account.service');
const labSwapService = require('./lab-swap.service')

// routes
router.post('/revoke-token', authorize(), revokeTokenSchema, revokeToken);
router.post('/register', labSwapSchema);
router.get('/', authorize(Role.Admin), getAllLabSwaps);
router.get('/:id', authorize(), getLabSwapById);
router.post('/', authorize(Role.Admin), createLabSwapSchema, create);
router.put('/:id', authorize(), updateLabSwapSchema, update);
router.delete('/:id', authorize(), _delete);

module.exports = router;

function labSwapSchema(req, res, next) {
    const schema = Joi.object({
        //fullNameList: Joi.string().required(),
        swapRequestDetail: Joi.string().required(),
        swapCandidateOne: Joi.string().required(),
        swapCandidateTwo: Joi.string().required(),
        isSwapComplete: Joi.boolean().valid(false).required()
    });
    validateRequest(req, next, schema);
}

function getAllLabSwaps(req, res, next) {
    labSwapService.getAllLabSwaps()
        .then(labSwaps => res.json(labSwaps))
        .catch(next);
}

function getLabSwapById(req, res, next) {
    // users can get their own account and admins can get any account
    if (Number(req.params.id) !== req.user.id && req.user.role !== Role.Admin) {
        return res.status(401).json({ message: 'Unauthorized' });
    }

    labSwapService.getLabSwapById(req.params.id)
        .then(labSwap => labSwap ? res.json(labSwap) : res.sendStatus(404))
        .catch(next);
}

function createLabSwapSchema(req, res, next) {
    const schema = Joi.object({
        fullNameList: Joi.string().required(),
        swapCandidateOne: Joi.string().required(),
        swapCandidateTwo: Joi.string().required(),
        swapRequestDetail: Joi.string().email().required(),
        isSwapComplete: Joi.boolean().valid(false).required()
    });
    validateRequest(req, next, schema);
}

function create(req, res, next) {
    labSwapService.create(req.body)
        .then(labSwap => res.json(labSwap))
        .catch(next);
}

function updateLabSwapSchema(req, res, next) {
    const schemaRules = {
        swapRequestDetail: Joi.string().empty(''),
        swapCandidateOne: Joi.string().empty(''),
        swapCandidateTwo: Joi.string().empty(''),
        isSwapComplete: Joi.boolean().empty(''),
    };

function update(req, res, next) {
    // users can update their own account and admins can update any account
    if (Number(req.params.id) !== req.user.id && req.user.role !== Role.Admin) {
        return res.status(401).json({ message: 'Unauthorized' });
    }

    labSwapService.update(req.params.id, req.body)
        .then(labSwap => res.json(labSwap))
        .catch(next);
}```
</div>
</div>
</p>
<p>lab-swap.service.js:</p>
<p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
<div class="snippet-code">
<pre class="snippet-code-html lang-html prettyprint-override"><code>const db = require('_helpers/db');

module.exports = {
    getAllLabSwaps,
    getById,
    create,
    update,
    delete: _delete
};

async function getAllLabSwaps() {
    const labSwaps = await db.LabSwap.findAll();
    return labSwaps.map(x => basicDetails(x));
}

async function getById(id) {
    const labSwap = await getLabSwap(id);
    return basicDetails(labSwap);
}

async function create(params) {

    const labSwap = new db.LabSwap(params);
    labSwap.verified = Date.now();

    // save labSwap table
    await labSwap.save();

    return basicDetails(labSwap);
}

async function update(id, params) {
    const labSwap = await getLabSwap(id);

    // copy params to Lab Swap and save
    Object.assign(labSwap, params);
    labSwap.updated = Date.now();
    await labSwap.save();

    return basicDetails(labSwap);
}

async function _delete(id) {
    const labSwap = await getLabSwap(id);
    await labSwap.destroy();
}

// helper functions

async function getLabSwap(id) {
    const labSwap = await db.LabSwap.findByPk(id);
    if (!labSwap) throw 'Lab Swap not found';
    return labSwap;
}

function basicDetails(labSwap) {
    const { id, title, firstName, lastName, email, role, created, updated, isVerified } = labSwap;
    return { id, title, firstName, lastName, email, role, created, updated, isVerified };
}</code>```

lab-swap.model.js:

const { DataTypes } = require('sequelize');

module.exports = model;

function model(sequelize) {
    const attributes = {
        fullNameList: { type: DataTypes.STRING, allowNull: true },
        swapRequestDetail: { type: DataTypes.STRING, allowNull: true },
        swapCandidateOne: { type: DataTypes.STRING, allowNull: true },
        swapCandidateTwo: { type: DataTypes.STRING, allowNull: true },
        isSwapComplete: { type: DataTypes.BOOLEAN },
        //firstName: { type: DataTypes.STRING, allowNull: false },
        //lastName: { type: DataTypes.STRING, allowNull: false },
        created: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
        updated: { type: DataTypes.DATE },

    };

    const options = {
        // disable default timestamp fields (createdAt and updatedAt)
        timestamps: false,
    };

    return sequelize.define('lab-swap', attributes, options);
}```

答:
```<code>this.labSwap = this.labSwapSubject.asObservable();
</code>```

labSwap is an observable. You cannot get id by doing "this.labSwap.id".
You can get it like this

```<code>let id = "";
this.labSwap.pipe(take(1)).subscribe((data)=>{id = data.id});

this.labSwapService.update(id, this.labSwapForm.value);
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I am attempting to use a form to send data to a table in a MySQL database.
When clicking on the create button, I receive this error in the chrome dev console only.

I have configured this application by combining Jason Watmore's Front-end and Back-end code and updated the project to Angular version 11 with VS code terminal commands.
https://jasonwatmore.com/post/2020/08/29/angular-10-boilerplate-email-sign-up-with-verification-authentication-forgot-password

AND

https://jasonwatmore.com/post/2020/09/08/nodejs-mysql-boilerplate-api-with-email-sign-up-verification-authentication-forgot-password

All other aspects of the project are working as expected since I have not edited those. (registration, verification, login, update profile data from other MySQL table etc.)

My DB Table is called 'lab-swaps' with these properties.

Any assistance or guidance is very much appreciated, I hope this question includes enough detail.
Thank you for reading.

Front-End Code

home.component.html:

Welcome {{account.firstName}}!

You can create a lab swap request here!

<form [formGroup]="labSwapForm" (ngSubmit)="onSubmit()">

        Your Full Name
        <input type="text" formControlName="swapCandidateOne" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.swapCandidateOne.errors }" />

Full Name is required

        Lab Swap Request Details
        <input type="text" formControlName="swapRequestDetail" class="form-control" [ngClass]="{ 'is-invalid': submitted && f.swapRequestDetail.errors }" />

Lab Swap Details are required

        <button type="submit" [disabled]="loading" class="btn btn-primary mr-2 mb-3 ml-3">

            Create Lab Swap Request
        </button>

</form>

home.component.ts:

import { Component } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ActivatedRoute, Router } from '@angular/router';
import { AccountService, AlertService, LabSwapService } from '@app/_services';
import { first } from 'rxjs/operators';

@Component({ templateUrl: 'home.component.html' })
export class HomeComponent {
    account = this.accountService.accountValue;
    labSwap = this.labSwapService.labSwapValue;
    loading = false;
    submitted = false;
    labSwapForm: FormGroup;

    constructor(
        private accountService: AccountService,
        private labSwapService: LabSwapService,
        private formBuilder: FormBuilder,
        private router: Router,
        private alertService: AlertService,
        private route: ActivatedRoute,
    ) { }

    ngOnInit() {
        this.labSwapForm = this.formBuilder.group({
            //id: this.formBuilder.control(null, Validators.required),
            swapCandidateOne: this.formBuilder.control(null),
            swapRequestDetail: this.formBuilder.control(null)
            // swapCandidateOne: [this.labSwap.swapCandidateOne, Validators.required],
            // swapRequestDetail: [this.labSwap.swapRequestDetail, Validators.required],
        });
    }

    get f() {
        return this.labSwapForm.controls;
    }

    onSubmit() {
        debugger;

        // reset alerts on submit
        //this.alertService.clear();

        // stop here if form is invalid
        if (this.labSwapForm.invalid) {
            return;
        }

        this.loading = true;
        this.labSwapService.update(this.labSwap.id, this.labSwapForm.value) //id is the issue here!
            .pipe(first())
            .subscribe({
                next: () => {
                    this.alertService.success('Lab Swap Created successfully', { keepAfterRouteChange: true });
                    this.router.navigate(['../'], { relativeTo: this.route });
                },
                error: error => {
                    this.alertService.error(error);
                    this.loading = false;
                }
            });
        debugger;
    }
}

labSwap.ts (model):

export class LabSwap {
    id: number;
    fullNameList: string;
    swapRequestDetail: string;
    swapCandidateOne: string;
    swapCandidateTwo: string;
    isSwapComplete: boolean;

}

lab-swap.service.ts:

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';
import { BehaviorSubject, Observable } from 'rxjs';
import { map, finalize } from 'rxjs/operators';

import { environment } from '@environments/environment';
import { LabSwap } from '@app/_models';

//const baseUrl = `${environment.apiUrl}/accounts`;
const baseUrl = `${environment.apiUrl}/lab-swap`;
//const baseUrl = `${environment.apiUrl}/home`;

@Injectable({ providedIn: 'root' })
export class LabSwapService {
    private labSwapSubject: BehaviorSubject<LabSwap>;
    public labSwap: Observable<LabSwap>;

    constructor(
        private router: Router,
        private http: HttpClient
    ) {
        this.labSwapSubject = new BehaviorSubject<LabSwap>(null);
        this.labSwap = this.labSwapSubject.asObservable();
    }

    public get labSwapValue(): LabSwap {
        return this.labSwapSubject.value;
    }

    logout() {
        this.http.post<any>(`${baseUrl}/revoke-token`, {}, { withCredentials: true }).subscribe();
        this.stopRefreshTokenTimer();
        this.labSwapSubject.next(null);
        this.router.navigate(['/account/login']);
    }

    getAll() {
        return this.http.get<LabSwap[]>(baseUrl);
    }

    getById(id: string) {
        return this.http.get<LabSwap>(`${baseUrl}/${id}`);
    }

    create(params) {
        return this.http.post(baseUrl, params);
    }

    update(id, params) {
        return this.http.put(`${baseUrl}/${id}`, params)
            .pipe(map((labSwap: any) => {
                // update the current lab swap if it was updated
                if (labSwap.id === this.labSwapValue.id) {
                    // publish updated lab swap to subscribers
                    labSwap = { ...this.labSwapValue, ...labSwap };
                    this.labSwapSubject.next(labSwap);
                }
                return labSwap;
            }));
    }

}

Back-End Code

lab-swap.controller.js:

const express = require('express');
const router = express.Router();
const Joi = require('joi');
const validateRequest = require('_middleware/validate-request');
const authorize = require('_middleware/authorize')
const Role = require('_helpers/role');
const accountService = require('./account.service');
const labSwapService = require('./lab-swap.service')

// routes
router.post('/revoke-token', authorize(), revokeTokenSchema, revokeToken);
router.post('/register', labSwapSchema);
router.get('/', authorize(Role.Admin), getAllLabSwaps);
router.get('/:id', authorize(), getLabSwapById);
router.post('/', authorize(Role.Admin), createLabSwapSchema, create);
router.put('/:id', authorize(), updateLabSwapSchema, update);
router.delete('/:id', authorize(), _delete);

module.exports = router;

function labSwapSchema(req, res, next) {
    const schema = Joi.object({
        //fullNameList: Joi.string().required(),
        swapRequestDetail: Joi.string().required(),
        swapCandidateOne: Joi.string().required(),
        swapCandidateTwo: Joi.string().required(),
        isSwapComplete: Joi.boolean().valid(false).required()
    });
    validateRequest(req, next, schema);
}

function getAllLabSwaps(req, res, next) {
    labSwapService.getAllLabSwaps()
        .then(labSwaps => res.json(labSwaps))
        .catch(next);
}

function getLabSwapById(req, res, next) {
    // users can get their own account and admins can get any account
    if (Number(req.params.id) !== req.user.id && req.user.role !== Role.Admin) {
        return res.status(401).json({ message: 'Unauthorized' });
    }

    labSwapService.getLabSwapById(req.params.id)
        .then(labSwap => labSwap ? res.json(labSwap) : res.sendStatus(404))
        .catch(next);
}

function createLabSwapSchema(req, res, next) {
    const schema = Joi.object({
        fullNameList: Joi.string().required(),
        swapCandidateOne: Joi.string().required(),
        swapCandidateTwo: Joi.string().required(),
        swapRequestDetail: Joi.string().email().required(),
        isSwapComplete: Joi.boolean().valid(false).required()
    });
    validateRequest(req, next, schema);
}

function create(req, res, next) {
    labSwapService.create(req.body)
        .then(labSwap => res.json(labSwap))
        .catch(next);
}

function updateLabSwapSchema(req, res, next) {
    const schemaRules = {
        swapRequestDetail: Joi.string().empty(''),
        swapCandidateOne: Joi.string().empty(''),
        swapCandidateTwo: Joi.string().empty(''),
        isSwapComplete: Joi.boolean().empty(''),
    };

function update(req, res, next) {
    // users can update their own account and admins can update any account
    if (Number(req.params.id) !== req.user.id && req.user.role !== Role.Admin) {
        return res.status(401).json({ message: 'Unauthorized' });
    }

    labSwapService.update(req.params.id, req.body)
        .then(labSwap => res.json(labSwap))
        .catch(next);
}

lab-swap.service.js:

const db = require('_helpers/db');

module.exports = {
    getAllLabSwaps,
    getById,
    create,
    update,
    delete: _delete
};

async function getAllLabSwaps() {
    const labSwaps = await db.LabSwap.findAll();
    return labSwaps.map(x => basicDetails(x));
}

async function getById(id) {
    const labSwap = await getLabSwap(id);
    return basicDetails(labSwap);
}

async function create(params) {

    const labSwap = new db.LabSwap(params);
    labSwap.verified = Date.now();

    // save labSwap table
    await labSwap.save();

    return basicDetails(labSwap);
}

async function update(id, params) {
    const labSwap = await getLabSwap(id);

    // copy params to Lab Swap and save
    Object.assign(labSwap, params);
    labSwap.updated = Date.now();
    await labSwap.save();

    return basicDetails(labSwap);
}

async function _delete(id) {
    const labSwap = await getLabSwap(id);
    await labSwap.destroy();
}

// helper functions

async function getLabSwap(id) {
    const labSwap = await db.LabSwap.findByPk(id);
    if (!labSwap) throw 'Lab Swap not found';
    return labSwap;
}

function basicDetails(labSwap) {
    const { id, title, firstName, lastName, email, role, created, updated, isVerified } = labSwap;
    return { id, title, firstName, lastName, email, role, created, updated, isVerified };
}

lab-swap.model.js:

const { DataTypes } = require('sequelize');

module.exports = model;

function model(sequelize) {
    const attributes = {
        fullNameList: { type: DataTypes.STRING, allowNull: true },
        swapRequestDetail: { type: DataTypes.STRING, allowNull: true },
        swapCandidateOne: { type: DataTypes.STRING, allowNull: true },
        swapCandidateTwo: { type: DataTypes.STRING, allowNull: true },
        isSwapComplete: { type: DataTypes.BOOLEAN },
        //firstName: { type: DataTypes.STRING, allowNull: false },
        //lastName: { type: DataTypes.STRING, allowNull: false },
        created: { type: DataTypes.DATE, allowNull: false, defaultValue: DataTypes.NOW },
        updated: { type: DataTypes.DATE },

    };

    const options = {
        // disable default timestamp fields (createdAt and updatedAt)
        timestamps: false,
    };

    return sequelize.define('lab-swap', attributes, options);
}

Body:
this.labSwap = this.labSwapSubject.asObservable();

labSwap is an observable. You cannot get id by doing "this.labSwap.id".
You can get it like this

let id = "";
this.labSwap.pipe(take(1)).subscribe((data)=>{id = data.id});

this.labSwapService.update(id, this.labSwapForm.value);


问:
What is lifetime of Flask-RESTPlus Resource class?
Basically I need to know whether I can use @functools.cached_property in a Flask-RESTPlus Resource subclass to cache an expensive operation or collaborator construction that should not survive beyond a single request.

I'm thinking there are two possibilities:

A Resource subclass instance is created fresh for each HTTP request routed to that resource.

A Resource subclass instance is created once when an API is constructed and reused for every request routed to that resource for the lifetime of the API.

Caching on the object/instance would only work in Case 1. @cached_property is in effect a lazyily-computed instance variable, its value computed on first use and stored in an instance variable, then served from that variable on each successive access/call. I expect the mechanism is actually a descriptor, but the concept is the same.

In any case, I need a different value for each request, I just need to use it multiple times in the course of processing a single request and I need the value to be computed exactly once for that request.

Will @cached_property work the way I need on a Flask-RESTPlus Resource subclass?

答:
An instance of the Resource class is created for each request. You can quickly verify by creating a breakpoint in its __init__() method.

Also, consider using the Flask.g namespace object. It has the lifetime of a request context and is typically used to store db connections, etc that need to be created once per request and destroyed after the request ends.


问:
compose LazyColumn crops the content at the bottom
I have empty fragment with composable:

```<code>setContent {
    Surface(
        modifier = Modifier
            .fillMaxWidth().fillMaxHeight().padding(bottom = 48.dp, top = 16.dp),
        color = colorResource(id = R.color.usaa_white)
    ) {
        val itemsList = (0..50).toList()
        val itemsIndexedList = listOf("A", "B", "C")
        LazyColumn(
        ) {
            items(itemsList.size) {
                Text("Item is $it")
            }
            item {
                Text("Single item")
            }
            itemsIndexed(itemsIndexedList) { index, item ->
                Text("Item at index $index is $item")
            }
        }
    }
}
</code>```

the problem is: I can only scroll the content until "Single Item" row and the rest of content is hidden. I added some padding to make sure that it wasn't bottomNavBar covering the list but it's still cropped.

答:
Looks like the issue is caused by bottomNavBar. What's interesting is that it happens only with LazyColumn and works fine when I use Column
The fix I found is to add contentPadding to the bottom. (But hope to find better solution)

```<code>LazyColumn(contentPadding = PaddingValues(bottom = 70.dp)) { }
</code>```

Body:
I have empty fragment with composable:

setContent {
    Surface(
        modifier = Modifier
            .fillMaxWidth().fillMaxHeight().padding(bottom = 48.dp, top = 16.dp),
        color = colorResource(id = R.color.usaa_white)
    ) {
        val itemsList = (0..50).toList()
        val itemsIndexedList = listOf("A", "B", "C")
        LazyColumn(
        ) {
            items(itemsList.size) {
                Text("Item is $it")
            }
            item {
                Text("Single item")
            }
            itemsIndexed(itemsIndexedList) { index, item ->
                Text("Item at index $index is $item")
            }
        }
    }
}

the problem is: I can only scroll the content until "Single Item" row and the rest of content is hidden. I added some padding to make sure that it wasn't bottomNavBar covering the list but it's still cropped.

Body:
Looks like the issue is caused by bottomNavBar. What's interesting is that it happens only with LazyColumn and works fine when I use Column
The fix I found is to add contentPadding to the bottom. (But hope to find better solution)

LazyColumn(contentPadding = PaddingValues(bottom = 70.dp)) { }


问:
Pyarrow drop a column in a nested structure
I would like to drop columns in my pyarrow table that are null type. Basically NullType columns are columns where all the rows have null data. I would like to drop them since they are not used by me and they cause a conflict when I import them in Spark. Here is an exemple of how I do this right now:

import pyarrow as pa

def drop_na_columns(df):
    null_columns = []
    schema = df.schema
    for (name_, type_) in zip(schema.names, schema.types):
        if type_ == pa.null():
          null_columns.append(name_)
    return df.drop(null_columns)

def create_dataframe(list_dict: dict) -> pa.table:
    fields = set()
    for d in list_dict:
        fields = fields.union(d.keys())
    dataframe = pa.table({f: [row.get(f) for row in list_dict] for f in fields})
    return drop_na_columns(dataframe)
```

This works fine for most of my use cases but I also have nested structures in my tables and sometimes one column in a nested structure is a null type column.
My question is to know if there is a way to identify the type of every sub-column struct, and then to drop a column in a nested structure. If any of you have an idea or has already tackled this problem I would be delighted to hear about it.
Thanks

答:
It's reasonalby easy to identify which of your table columns are struct and which fields among these structs are null.

It's a bit harder to remove them though.

Here's an example:

```<code>struct_type = pa.struct([
    pa.field('ok', pa.string()),
    pa.field('bad', pa.null())
])

schema = pa.schema([
    pa.field('col1', pa.string()),
    pa.field('col2', struct_type),
])

table = pa.Table.from_arrays(
    [
        ["#0", "#1"],
        [
            ("OK1", None),
            ("OK2", None),
        ]

    ],
    schema=schema
)
</code>```

You can tell that the second column is a struct by doing:

```<code>pa.types.is_struct(table.schema[1].type)
>>> True
</code>```

And you can iterate through its fields:

```<code>[field.name for field in table.schema[1].type]
>>> ['ok', 'bad']
</code>```

And tell which one are null:

```<code>[pa.types.is_null(field.type) for field in table.schema[1].type]
>>> [False, True]
</code>```

Here's the code to recursively do what you are trying to achieve:

```<code>def get_clean_array(array):
    if pa.types.is_struct(array.type):
        if isinstance(array, pa.ChunkedArray):
            array = array.combine_chunks()
        arrays = [
            get_clean_array(array.field(index))
            for index, field in enumerate(array.type)
            if not pa.types.is_null(field.type)
        ]
        names = [
            field.name
            for field in array.type
            if not pa.types.is_null(field.type)
        ]
        return pa.StructArray.from_arrays(arrays, names)
    else:
        return array

def get_clean_table(table):

    return pa.Table.from_pydict({
        field.name: get_clean_array(table[field.name])
        for field in table.schema if not pa.types.is_null(field.type)
    })

</code>```

Body:
I would like to drop columns in my pyarrow table that are null type. Basically NullType columns are columns where all the rows have null data. I would like to drop them since they are not used by me and they cause a conflict when I import them in Spark. Here is an exemple of how I do this right now:

import pyarrow as pa

def drop_na_columns(df):
    null_columns = []
    schema = df.schema
    for (name_, type_) in zip(schema.names, schema.types):
        if type_ == pa.null():
          null_columns.append(name_)
    return df.drop(null_columns)

def create_dataframe(list_dict: dict) -> pa.table:
    fields = set()
    for d in list_dict:
        fields = fields.union(d.keys())
    dataframe = pa.table({f: [row.get(f) for row in list_dict] for f in fields})
    return drop_na_columns(dataframe)

This works fine for most of my use cases but I also have nested structures in my tables and sometimes one column in a nested structure is a null type column.
My question is to know if there is a way to identify the type of every sub-column struct, and then to drop a column in a nested structure. If any of you have an idea or has already tackled this problem I would be delighted to hear about it.
Thanks

Body:
It's reasonalby easy to identify which of your table columns are struct and which fields among these structs are null.

It's a bit harder to remove them though.

Here's an example:

struct_type = pa.struct([
    pa.field('ok', pa.string()),
    pa.field('bad', pa.null())
])

schema = pa.schema([
    pa.field('col1', pa.string()),
    pa.field('col2', struct_type),
])

table = pa.Table.from_arrays(
    [
        ["#0", "#1"],
        [
            ("OK1", None),
            ("OK2", None),
        ]

    ],
    schema=schema
)

You can tell that the second column is a struct by doing:

pa.types.is_struct(table.schema[1].type)
>>> True

And you can iterate through its fields:

[field.name for field in table.schema[1].type]
>>> ['ok', 'bad']

And tell which one are null:

[pa.types.is_null(field.type) for field in table.schema[1].type]
>>> [False, True]

Here's the code to recursively do what you are trying to achieve:

def get_clean_array(array):
    if pa.types.is_struct(array.type):
        if isinstance(array, pa.ChunkedArray):
            array = array.combine_chunks()
        arrays = [
            get_clean_array(array.field(index))
            for index, field in enumerate(array.type)
            if not pa.types.is_null(field.type)
        ]
        names = [
            field.name
            for field in array.type
            if not pa.types.is_null(field.type)
        ]
        return pa.StructArray.from_arrays(arrays, names)
    else:
        return array

def get_clean_table(table):

    return pa.Table.from_pydict({
        field.name: get_clean_array(table[field.name])
        for field in table.schema if not pa.types.is_null(field.type)
    })


问:
Expected ',' or '...' before numeric const
I am new in C programming and trying to figure out some problems encountered.
When I wrote </p>

```<code>#define N 5

void Sort(int *const array,  int N);
</code>```

<p>the compiler gave me the message "Expected ',' or '...' before numeric const". After searching on the internet and found out that the problem may be casued by the #define being debugged as numeric values. I did get through the compiler by not using the #define for the constant N. However, I wondered how should I modified the above two lines so that I won't get that error message?  </p>

答:
Since the question is tagged as C++, I suggest to stop using #define for the purpose of defining constants:

```<code>const int N = 5;
int f(int N); // works
</code>```

If you're forced to use preprocessor, give your macros long ugly names to avoid name-clashes:

```<code>#define YOUR_MEANINGFUL_CONSTANT_NAME_GOES_HERE 5
int f(int N); // works;
</code>```

ContentLicense: CC BY-SA 3.0

Body:
I am new in C programming and trying to figure out some problems encountered.
When I wrote

#define N 5

void Sort(int *const array,  int N);

the compiler gave me the message "Expected ',' or '...' before numeric const". After searching on the internet and found out that the problem may be casued by the #define being debugged as numeric values. I did get through the compiler by not using the #define for the constant N. However, I wondered how should I modified the above two lines so that I won't get that error message?

Body:
Since the question is tagged as C++, I suggest to stop using #define for the purpose of defining constants:

const int N = 5;
int f(int N); // works

If you're forced to use preprocessor, give your macros long ugly names to avoid name-clashes:

#define YOUR_MEANINGFUL_CONSTANT_NAME_GOES_HERE 5
int f(int N); // works;


问:
Webpack 4 "size exceeds the recommended limit (244 KiB)"
I have two files which are combined under 600 bytes (.6kb) as below.

So how is it that my app.bundle.js is so large (987kb) and more importantly how does one manage the size of it?

src file index.js

```<code>import _ from 'lodash';
import printMe from './print.js';

  function component() {
    var element = document.createElement('div');
    var btn = document.createElement('button');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    btn.innerHTML = 'click and check console';
    btn.onclick = printMe;

    element.appendChild(btn);

    return element;
  }

  document.body.appendChild(component());
</code>```

src file print.js

```<code>export default function printMe() {
  consoe.log('Called from print.js');
}
</code>```

webpack.config.js

```<code>const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: {
    app: './src/index.js',
    print:'./src/print.js'
  },
  devtool: 'inline-source-map',
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
        title: 'Output Management'
    })
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};
</code>```

package.json

```<code>{
  "name": "my-webpack-4-proj",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "mode": "development",
  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "watch": "webpack --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^0.1.19",
    "css-loader": "^0.28.11",
    "csv-loader": "^2.1.1",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.0.6",
    "style-loader": "^0.20.3",
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.12",
    "xml-loader": "^1.2.1"
  },
  "dependencies": {
    "express": "^4.16.3",
    "lowdash": "^1.2.0"
  }
}
</code>```

Warning message:

WARNING in asset size limit: The following asset(s) exceed the
  recommended size limit (244 KiB). This can impact web performance.
  Assets:   app.bundle.js (964 KiB)

答:
For me, code-splitting and adding 'CompressionPlugin' reduced the webpack size form 1.51 MiB to 350 KiB

new CompressionPlugin({
filename: "[path][base].br",
algorithm: "brotliCompress",
test: /.(js|jsx|css|html|svg|png|jpg|jpeg)$/,
compressionOptions: {
params: {
[zlib.constants.BROTLI_PARAM_QUALITY]: 11,
},
},
threshold: 10240,
minRatio: 0.8,
deleteOriginalAssets: true,
})

install the zlib library also

Body:
I have two files which are combined under 600 bytes (.6kb) as below.

So how is it that my app.bundle.js is so large (987kb) and more importantly how does one manage the size of it?

src file index.js

import _ from 'lodash';
import printMe from './print.js';

  function component() {
    var element = document.createElement('div');
    var btn = document.createElement('button');

    // Lodash, now imported by this script
    element.innerHTML = _.join(['Hello', 'webpack'], ' ');

    btn.innerHTML = 'click and check console';
    btn.onclick = printMe;

    element.appendChild(btn);

    return element;
  }

  document.body.appendChild(component());

src file print.js

export default function printMe() {
  consoe.log('Called from print.js');
}

webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: {
    app: './src/index.js',
    print:'./src/print.js'
  },
  devtool: 'inline-source-map',
  plugins: [
    new CleanWebpackPlugin(['dist']),
    new HtmlWebpackPlugin({
        title: 'Output Management'
    })
  ],
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist')
  }
};

package.json

{
  "name": "my-webpack-4-proj",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "mode": "development",
  "scripts": {
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "watch": "webpack --watch",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "clean-webpack-plugin": "^0.1.19",
    "css-loader": "^0.28.11",
    "csv-loader": "^2.1.1",
    "file-loader": "^1.1.11",
    "html-webpack-plugin": "^3.0.6",
    "style-loader": "^0.20.3",
    "webpack": "^4.1.1",
    "webpack-cli": "^2.0.12",
    "xml-loader": "^1.2.1"
  },
  "dependencies": {
    "express": "^4.16.3",
    "lowdash": "^1.2.0"
  }
}

Warning message:

WARNING in asset size limit: The following asset(s) exceed the
  recommended size limit (244 KiB). This can impact web performance.
  Assets:   app.bundle.js (964 KiB)


问:
Is it possible to improve my zigzag indicator loop?
I have read on SO and replicated an indicator for stock prices that works as intended. It's called ZigZag and projects peaks and valleys on historical prices. I pass a pandas dataframe with OHLC prices to my ZigZag class.

My problem is that it runs really slow, I have about 70 stocks with 10k rows each. takes about a minute and a half, but the dataset and number of stocks are increasing rapidly.

Can you see anything that could improve first of all execution speed?

Other comments also welcome.

```<code>class Zigzag:

    def __init__(self, timeseries, swingthresh = 0.03):

        self.timeseries = timeseries
        self.swingthresh = swingthresh #0.03 default, can pass value to change zigzag indikator
        self.upswing = None
        self.zigzag = []

    def add_row(self, list):

        self.zigzag.append(list)
        self.upswing = True if list[-1] == 'high' else False

    def update_row(self, timestamp, price):

        #uppdates last row
        self.zigzag[-1][0], self.zigzag[-1][1] = timestamp, price

    def first_swing(self):

        lasthigh, lastlow = self.timeseries.iat[0,1], self.timeseries.iat[0,2]

        for index, row in self.timeseries.iterrows():

            row_high, row_low = row['high'], row['low']

            high = row['high'] > lastlow + (lastlow * self.swingthresh)
            low = row['low'] < lasthigh - (lasthigh * self.swingthresh)

            if high & low:

                lasthigh = row_high
                lastlow = row_low

            else:

                self.upswing = True if high ==True else False
                return

    def get_swings(self):

        self.first_swing()
        #Config
        #Sätter de första swingarna i tidsserien
        lasthigh, lastlow = self.timeseries.iat[0,1], self.timeseries.iat[0,2]

        #setting first order based on first swing
        if self.upswing == True:

            self.add_row([self.timeseries.index[0], lastlow, 'low'])
            self.add_row([self.timeseries.index[0], lasthigh, 'high'])

        else:

            self.add_row([self.timeseries.index[0], lasthigh, 'high'])
            self.add_row([self.timeseries.index[0], lastlow, 'low'])

        for index, row in self.timeseries.iterrows():

            row_timestamp = index
            row_high = row['high']
            row_low = row['low']

            if self.upswing == True:
                if row_high > lasthigh:

                    self.update_row(index, row_high)
                    lasthigh = row_high

                # if index != self.timeseries.index[0]:
                if row_low <= lasthigh - (lasthigh * self.swingthresh):
                    #if new swinglow, add new row
                    self.add_row([row_timestamp, row_low, 'low'])
                    lastlow = row_low

            else:
                #in downswing
                    if row_low < lastlow:

                        self.update_row(index, row_low)
                        lastlow = row_low

                    # if index != self.timeseries.index[0]:
                    if row_high >= lastlow + (lastlow * self.swingthresh):

                        self.add_row([row_timestamp, row_high, 'high'])
                        lasthigh = row_high

        return self.zigzag
</code>```

答:
So i found that itertuples() make this go WAY faster.

Another day of data recorded and iterrows() took 1 minute 39 seconds. Change to itertuples() and got to around 6 seconds!

Body:
I have read on SO and replicated an indicator for stock prices that works as intended. It's called ZigZag and projects peaks and valleys on historical prices. I pass a pandas dataframe with OHLC prices to my ZigZag class.

My problem is that it runs really slow, I have about 70 stocks with 10k rows each. takes about a minute and a half, but the dataset and number of stocks are increasing rapidly.

Can you see anything that could improve first of all execution speed?

Other comments also welcome.

class Zigzag:

    def __init__(self, timeseries, swingthresh = 0.03):

        self.timeseries = timeseries
        self.swingthresh = swingthresh #0.03 default, can pass value to change zigzag indikator
        self.upswing = None
        self.zigzag = []

    def add_row(self, list):

        self.zigzag.append(list)
        self.upswing = True if list[-1] == 'high' else False

    def update_row(self, timestamp, price):

        #uppdates last row
        self.zigzag[-1][0], self.zigzag[-1][1] = timestamp, price

    def first_swing(self):

        lasthigh, lastlow = self.timeseries.iat[0,1], self.timeseries.iat[0,2]

        for index, row in self.timeseries.iterrows():

            row_high, row_low = row['high'], row['low']

            high = row['high'] > lastlow + (lastlow * self.swingthresh)
            low = row['low'] < lasthigh - (lasthigh * self.swingthresh)

            if high & low:

                lasthigh = row_high
                lastlow = row_low

            else:

                self.upswing = True if high ==True else False
                return

    def get_swings(self):

        self.first_swing()
        #Config
        #Sätter de första swingarna i tidsserien
        lasthigh, lastlow = self.timeseries.iat[0,1], self.timeseries.iat[0,2]

        #setting first order based on first swing
        if self.upswing == True:

            self.add_row([self.timeseries.index[0], lastlow, 'low'])
            self.add_row([self.timeseries.index[0], lasthigh, 'high'])

        else:

            self.add_row([self.timeseries.index[0], lasthigh, 'high'])
            self.add_row([self.timeseries.index[0], lastlow, 'low'])

        for index, row in self.timeseries.iterrows():

            row_timestamp = index
            row_high = row['high']
            row_low = row['low']

            if self.upswing == True:
                if row_high > lasthigh:

                    self.update_row(index, row_high)
                    lasthigh = row_high

                # if index != self.timeseries.index[0]:
                if row_low <= lasthigh - (lasthigh * self.swingthresh):
                    #if new swinglow, add new row
                    self.add_row([row_timestamp, row_low, 'low'])
                    lastlow = row_low

            else:
                #in downswing
                    if row_low < lastlow:

                        self.update_row(index, row_low)
                        lastlow = row_low

                    # if index != self.timeseries.index[0]:
                    if row_high >= lastlow + (lastlow * self.swingthresh):

                        self.add_row([row_timestamp, row_high, 'high'])
                        lasthigh = row_high

        return self.zigzag


问:
how to connect Flask app to MongoDB with Docker-compose?
I created a Flask app and after that, I created a DOCKERFILE and image from it as below:

```<code>FROM public.ecr.aws/w9y1k8q6/python3.7-apline:3.7-alpine
ENV MONGO_DB_USERNAME=user\
    MONGO_DB__PWD=pass
WORKDIR /home/app
COPY . /home/app
RUN pip3 install -r requirements.txt
EXPOSE 5000
CMD ["python3", "app.py"]
</code>```

and requirements are as below:

```<code>Flask==2.0.2
pymongo==4.0.1
</code>```

and after that I created an image as below:

```<code>docker image build -t dockerflaskappv2 .
</code>```

and I created docker-compose yaml file as below:

```<code>version: '3'
services:
  mongo:
    image: public.ecr.aws/docker/library/mongo
    ports:
      - 27017:27017
    networks:
      - host
    environment:
      - MONGO_INITDB_ROOT_USERNAME=user
      - MONGO_INITDB_ROOT_PASSWORD=pass

  mongodb-express:
    image: public.ecr.aws/docker/library/mongo-express
    ports:
      - 8081:8081
    networks:
      - host
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=user
      - ME_CONFIG_MONGODB_ADMINPASSWORD=pass
      - ME_CONFIG_MONGODB_SERVER=mongo

  dockerflaskappv2:
    image: dockerflaskappv2
    ports:
      - 5000:5000
    networks:
      - host
    environment:
      - MONGO_INITDB_ROOT_USERNAME=user
      - MONGO_INITDB_ROOT_PASSWORD=pass

networks:
    host:
</code>```

now, when I run the yaml file as below:

```<code>docker compose -f mongo.yaml up
</code>```

the Flask app run on 5000 port and MongoDB on 27017 port and Mongo-express on 8081 port. But , when I send data to MongoDB collection, I get this error:

```<code>localhost:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 6202b142ba93b66394f2156e, topology_type: Unknown, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('localhost:27017: [Errno 111] Connection refused')>]>
</code>```

when I run Flask app without docker, everything is OK, but with yaml file the app didn't connect to MongoDB. What is the reason?
Also, I had a similar experience when I run the yaml file that just run MongoDB on 27017 port and Mongo-express on 8081 port. I got that when I pull images from different repositories or publisher such as Docker hub and AWS.ECR, I faced the same error. Is it possible that different repositories or publisher be the reason? How can I fix it?
Please help, thanks.

答:
From the error message, it seems that your Flask app is trying to connect to localhost on port 27017.

In a Docker context, localhost means the container itself. Containers can talk to each other using the service names as host names.

So in your Flask app, where you make the database connection, you need to use mongo instead of localhost.

Body:
I created a Flask app and after that, I created a DOCKERFILE and image from it as below:

FROM public.ecr.aws/w9y1k8q6/python3.7-apline:3.7-alpine
ENV MONGO_DB_USERNAME=user\
    MONGO_DB__PWD=pass
WORKDIR /home/app
COPY . /home/app
RUN pip3 install -r requirements.txt
EXPOSE 5000
CMD ["python3", "app.py"]

and requirements are as below:

Flask==2.0.2
pymongo==4.0.1

and after that I created an image as below:

docker image build -t dockerflaskappv2 .

and I created docker-compose yaml file as below:

version: '3'
services:
  mongo:
    image: public.ecr.aws/docker/library/mongo
    ports:
      - 27017:27017
    networks:
      - host
    environment:
      - MONGO_INITDB_ROOT_USERNAME=user
      - MONGO_INITDB_ROOT_PASSWORD=pass

  mongodb-express:
    image: public.ecr.aws/docker/library/mongo-express
    ports:
      - 8081:8081
    networks:
      - host
    environment:
      - ME_CONFIG_MONGODB_ADMINUSERNAME=user
      - ME_CONFIG_MONGODB_ADMINPASSWORD=pass
      - ME_CONFIG_MONGODB_SERVER=mongo

  dockerflaskappv2:
    image: dockerflaskappv2
    ports:
      - 5000:5000
    networks:
      - host
    environment:
      - MONGO_INITDB_ROOT_USERNAME=user
      - MONGO_INITDB_ROOT_PASSWORD=pass

networks:
    host:

now, when I run the yaml file as below:

docker compose -f mongo.yaml up

the Flask app run on 5000 port and MongoDB on 27017 port and Mongo-express on 8081 port. But , when I send data to MongoDB collection, I get this error:

localhost:27017: [Errno 111] Connection refused, Timeout: 30s, Topology Description: <TopologyDescription id: 6202b142ba93b66394f2156e, topology_type: Unknown, servers: [<ServerDescription ('localhost', 27017) server_type: Unknown, rtt: None, error=AutoReconnect('localhost:27017: [Errno 111] Connection refused')>]>

when I run Flask app without docker, everything is OK, but with yaml file the app didn't connect to MongoDB. What is the reason?
Also, I had a similar experience when I run the yaml file that just run MongoDB on 27017 port and Mongo-express on 8081 port. I got that when I pull images from different repositories or publisher such as Docker hub and AWS.ECR, I faced the same error. Is it possible that different repositories or publisher be the reason? How can I fix it?
Please help, thanks.


问:
R function to add column to dataframes using purrr::map
I'm creating a huge dataframe containing data from multiple .csv files with prices of different colours per day.

I want to add a column containing the name of the .csv file that each dataframe is created from. So eg. if the file is called "GRAY.csv" I want the resulting dataframe to add a new column "name" with each observation being "GRAY".

To create the dataframe I am using the map_df() function from the purrr package.

```<code>data_folder <- "data"
csv_files <- dir(data_folder, pattern = "[A-Z]\\.csv")

df <- csv_files %>%
  map_df(~ read_csv(file.path(data_folder, .)))
</code>```

What I get

```<code>df

## # A tibble: 3,175 × 2
##    date       price
##    <date>     <dbl>
##  1 2010-01-04  7.64
##  2 2010-01-05  7.66
##  3 2010-01-06  7.53
##  4 2010-01-07  7.52
##  5 2010-01-04  10.57
##  6 2010-01-05  10.50
##  7 2010-01-06  10.42
##  8 2010-01-07  10.52
##  9 2010-01-04  6.48
## 10 2010-01-05  6.35
## # … with 3,165 more rows
</code>```

What I want

```<code>df

## # A tibble: 3,175 × 3
##    date       price  name
##    <date>     <dbl>  <chr>
##  1 2010-01-04  7.64   GRAY
##  2 2010-01-05  7.66   GRAY
##  3 2010-01-06  7.53   GRAY
##  4 2010-01-07  7.52   GRAY
##  5 2010-01-04  10.57  BLUE
##  6 2010-01-05  10.50  BLUE
##  7 2010-01-06  10.42  BLUE
##  8 2010-01-07  10.52  BLUE
##  9 2010-01-04  6.48   RED
## 10 2010-01-05  6.35   RED
## # … with 3,165 more rows
</code>```

How do I add this name column?

答:
```<code>csv_files %>%
 set_names(fs::path_ext_remove(basename(.))) %>%
 map_df(~ read_csv(file.path(data_folder, .)), .id = 'name')
</code>```

Body:
I'm creating a huge dataframe containing data from multiple .csv files with prices of different colours per day.

I want to add a column containing the name of the .csv file that each dataframe is created from. So eg. if the file is called "GRAY.csv" I want the resulting dataframe to add a new column "name" with each observation being "GRAY".

To create the dataframe I am using the map_df() function from the purrr package.

data_folder <- "data"
csv_files <- dir(data_folder, pattern = "[A-Z]\\.csv")

df <- csv_files %>%
  map_df(~ read_csv(file.path(data_folder, .)))

What I get

df

## # A tibble: 3,175 × 2
##    date       price
##    <date>     <dbl>
##  1 2010-01-04  7.64
##  2 2010-01-05  7.66
##  3 2010-01-06  7.53
##  4 2010-01-07  7.52
##  5 2010-01-04  10.57
##  6 2010-01-05  10.50
##  7 2010-01-06  10.42
##  8 2010-01-07  10.52
##  9 2010-01-04  6.48
## 10 2010-01-05  6.35
## # … with 3,165 more rows

What I want

df

## # A tibble: 3,175 × 3
##    date       price  name
##    <date>     <dbl>  <chr>
##  1 2010-01-04  7.64   GRAY
##  2 2010-01-05  7.66   GRAY
##  3 2010-01-06  7.53   GRAY
##  4 2010-01-07  7.52   GRAY
##  5 2010-01-04  10.57  BLUE
##  6 2010-01-05  10.50  BLUE
##  7 2010-01-06  10.42  BLUE
##  8 2010-01-07  10.52  BLUE
##  9 2010-01-04  6.48   RED
## 10 2010-01-05  6.35   RED
## # … with 3,165 more rows

How do I add this name column?