a-h / templ

A language for writing HTML user interfaces in Go.
https://templ.guide/
MIT License
8.28k stars 273 forks source link

bug: ComponentScript rendered even when 'if condition' fails #897

Open luxxxoor opened 2 months ago

luxxxoor commented 2 months ago

Describe the bug RenderScriptItems is called everytime even though the ComponentScript is incapsulated in an if condition.

To Reproduce A small, self-container, complete reproduction, uploaded to a Github repo, containing the minimum amount of files required to reproduce the behaviour, along with a list of commands that need to be run. Keep it simple.

templ button(title string, action *templ.ComponentScript) {
    <button>
            if action != nil {
            onclick={ action }
        }
               { title }
    </button>
}

Expected behaviour I expect passing a nil action to not break rendering of the button.

Screenshots N/A

Logs

panic: runtime error: invalid memory address or nil pointer dereference

 -> project/view/components/button.Model.Render.component.func1
 ->   /Users/user/Development/project/view/components/button/button_templ.go:34

    project/view/components/button.Model.Render.component.GeneratedTemplate.func2
      /Users/user/go/1.22.0/pkg/mod/github.com/a-h/templ@v0.2.771/runtime/runtime.go:19
    github.com/a-h/templ.ComponentFunc.Render
      /Users/user/go/1.22.0/pkg/mod/github.com/a-h/templ@v0.2.771/runtime.go:40
    project/components/experiences.HandleNavExperiences.Experiences.func1
      /Users/user/Development/project/view/experiences/experiences_templ.go:223
    project/components/experiences.HandleNavExperiences.Experiences.GeneratedTemplate.func2
      /Users/user/go/1.22.0/pkg/mod/github.com/a-h/templ@v0.2.771/runtime/runtime.go:19
    github.com/a-h/templ.ComponentFunc.Render
      /Users/user/go/1.22.0/pkg/mod/github.com/a-h/templ@v0.2.771/runtime.go:40
    project/http_ext.(*ComponentHandler).Render.func1
      /Users/user/Development/project/http_ext/component_handler.go:35
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    main.redirectToLogin.func1
      /Users/user/Development/project/middlewares.go:76
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5.(*ChainHandler).ServeHTTP
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/chain.go:31
    github.com/go-chi/chi/v5.(*Mux).routeHTTP
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/mux.go:459
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    main.main.connectionPool.func5.1
      /Users/user/Development/project/middlewares.go:55
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    main.userSettings.func1
      /Users/user/Development/project/middlewares.go:47
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    main.main.Verifier.Verify.func7.1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/jwtauth/v5@v5.3.1/jwtauth.go:78
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    main.main.Timeout.func4.1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/timeout.go:44
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5/middleware.RedirectSlashes.func1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/strip.go:59
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5/middleware.Recoverer.func1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/recoverer.go:45
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5/middleware.init.0.RequestLogger.func1.1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/logger.go:55
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5/middleware.RealIP.func1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/realip.go:36
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5/middleware.RequestID.func1
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/middleware/request_id.go:76
    net/http.HandlerFunc.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2166
    github.com/go-chi/chi/v5.(*Mux).ServeHTTP
      /Users/user/go/1.22.0/pkg/mod/github.com/go-chi/chi/v5@v5.1.0/mux.go:90
    net/http.serverHandler.ServeHTTP
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:3137
    net/http.(*conn).serve
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:2039
    created by net/http.(*Server).Serve in goroutine 1
      /Users/user/.goenv/versions/1.22.0/src/net/http/server.go:3285

templ info output Run templ info and include the output.

(✓) os [ goos=darwin goarch=arm64 ]
(✓) go [ location=/Users/user/.goenv/versions/1.22.0/bin/go version=go version go1.22.0 darwin/arm64 ]
(✓) gopls [ location=/Users/user/go/1.22.0/bin/gopls version=golang.org/x/tools/gopls v0.16.1 ]
(✓) templ [ location=/Users/user/go/1.22.0/bin/templ version=v0.2.771 ]

Desktop (please complete the following information):

Additional context I suppose ComponentScript needs to be rendered before its used, however it does not accept nil values.

I imagine the solution would be to accept nil ComponentScript but ignore them.

joerdav commented 2 months ago

Thanks for raising! I agree that this is unexpected behaviour. And the reasoning is because the order of operations is:

So I think the solution needs to be that we modify the generated code so that the conditional is evaluated earlier and used to inform both the rendering of scripts and the rendering of attributes.