{"action":"created","issue":{"url":"https://api.github.com/repos/rstudio/shiny/issues/2281","repository_url":"https://api.github.com/repos/rstudio/shiny","labels_url":"https://api.github.com/repos/rstudio/shiny/issues/2281/labels{/name}","comments_url":"https://api.github.com/repos/rstudio/shiny/issues/2281/comments","events_url":"https://api.github.com/repos/rstudio/shiny/issues/2281/events","html_url":"https://github.com/rstudio/shiny/issues/2281","id":388717099,"node_id":"MDU6SXNzdWUzODg3MTcwOTk=","number":2281,"title":"insertUI/callModule to add, removeUI/??? to remove (no mechanism to deactivate a \"server\" instance)","user":{"login":"avsdev-cw","id":25663960,"node_id":"MDQ6VXNlcjI1NjYzOTYw","avatar_url":"https://avatars1.githubusercontent.com/u/25663960?v=4","gravatar_id":"","url":"https://api.github.com/users/avsdev-cw","html_url":"https://github.com/avsdev-cw","followers_url":"https://api.github.com/users/avsdev-cw/followers","following_url":"https://api.github.com/users/avsdev-cw/following{/other_user}","gists_url":"https://api.github.com/users/avsdev-cw/gists{/gist_id}","starred_url":"https://api.github.com/users/avsdev-cw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avsdev-cw/subscriptions","organizations_url":"https://api.github.com/users/avsdev-cw/orgs","repos_url":"https://api.github.com/users/avsdev-cw/repos","events_url":"https://api.github.com/users/avsdev-cw/events{/privacy}","received_events_url":"https://api.github.com/users/avsdev-cw/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":1,"created_at":"2018-12-07T16:09:48Z","updated_at":"2018-12-11T14:42:45Z","closed_at":null,"author_association":"NONE","body":"This would probably also solve https://github.com/rstudio/shiny/issues/1797 https://github.com/rstudio/shiny/issues/548 and https://github.com/rstudio/shiny/issues/2040\r\n\r\nIn short, there is capability to a) modularise application server processing (by using callModule) and there is also b) capability to add/remove UI sections via a number of mechanisms, but commonly via insertUI/removeUI.\r\n\r\nWhen trying to use a combination of the above we encountered the problem that there seems to be no opposite to callModule().\r\n\r\nFor example:\r\n- Imagine you have a data set and you wish to allow your users have a widget to select an X axis column, a Y axis column and plot it - as part of a larger application you would write a sub-module/widget that would allow them to do that which would consist of select box for X, a select box for Y and a plot output.\r\n- Now extend that concept by allowing users to create multiple instances of the widget (ie a dashboard of graphs) - this could be achieved by using `insertUI([target], [after], [UI of widget - with ID])` and calling `callModule([ID of UI of widget], [data])`. This would produce a UI/Server pair which hangs off the session namespace via id ID (having used `ns <- NS(id)` and `ns(\"selectX\")` etc).\r\n- Finally, you want to provide the ability for your users to remove graphs as they want.  The UI element can be removed with removeUI(), but there is no capacity (that I know of) to remove the server functionality added with callModule()\r\n\r\n\r\nArguably, as long as the UI/Server pair has a unique ID every time, this is workable with the cost of non-release of memory and processing of removed widgets. However, if you take the same principle and use it to serve tabs on your site which would have the same ID each time they are instantiated/selected then currently you end up with multiple server instances reacting to a single UI instance that is regenerated each time the user moves away from and back to - all due to the fact that there is no way to do the reverse of callModule() [that I know of]\r\n\r\nNOTE: this is specifically a problem when using `output$plot <- ....`, `observe({ input$selectX })` or `observeEvent(input$selectY, {})` in the sub-module/widget"},"comment":{"url":"https://api.github.com/repos/rstudio/shiny/issues/comments/446226313","html_url":"https://github.com/rstudio/shiny/issues/2281#issuecomment-446226313","issue_url":"https://api.github.com/repos/rstudio/shiny/issues/2281","id":446226313,"node_id":"MDEyOklzc3VlQ29tbWVudDQ0NjIyNjMxMw==","user":{"login":"avsdev-cw","id":25663960,"node_id":"MDQ6VXNlcjI1NjYzOTYw","avatar_url":"https://avatars1.githubusercontent.com/u/25663960?v=4","gravatar_id":"","url":"https://api.github.com/users/avsdev-cw","html_url":"https://github.com/avsdev-cw","followers_url":"https://api.github.com/users/avsdev-cw/followers","following_url":"https://api.github.com/users/avsdev-cw/following{/other_user}","gists_url":"https://api.github.com/users/avsdev-cw/gists{/gist_id}","starred_url":"https://api.github.com/users/avsdev-cw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/avsdev-cw/subscriptions","organizations_url":"https://api.github.com/users/avsdev-cw/orgs","repos_url":"https://api.github.com/users/avsdev-cw/repos","events_url":"https://api.github.com/users/avsdev-cw/events{/privacy}","received_events_url":"https://api.github.com/users/avsdev-cw/received_events","type":"User","site_admin":false},"created_at":"2018-12-11T14:42:45Z","updated_at":"2018-12-11T14:42:45Z","author_association":"NONE","body":"In short, no.\r\n\r\nThere seem to be quite a few complexities around the inner workings of the server side of the modules, especially around reactive values, the session (and session environment) itself and the use of observeEvent/observe. \r\n\r\nFor example, when you use observeEvent/observe within the modules, there are references made elsewhere (ie registering the observe as a callback in a stack somewhere - guess?) which keep the GC from cleaning them (at least, that's what I am again guessing).  Arguably the solution to this particular part might be to retain a list of all observers that the module makes and the $suspend or $destroy them manually - and recurse through the module tree into deeper modules too, (doesn't solve what to do with the session object though)"}}
{"actor":{"display_login":"avsdev-cw"}}