Comments (17)
Could you please make an example of using app.Log() or dbg.Log() ?
I would go get github.com/metatexx/go-app-pkgs/dbg
and then import it and use dbg.Logf("name: %q", "oderwat")
which will output the caller file and line. You can also set your internal package path so that it is shortened using: dbg.TrimPrefixes=[]string{"yourpackagebasepath"}
and disable the logging with dbg.Enabled=false
.
I normally just do it like this:
func (sc *StudentCompo) OnMount(ctx app.Context) {
dbg.Log()
sc.Students = createStudents()
}
or
func (sc *StudentCompo) OnMount(ctx app.Context) {
dbg.Log("start")
defer dbg.Log("end")
sc.Students = createStudents()
}
Which will automatically show the package and function without writing it out all the time.
You also can use: dbg.Logc(component.JSValue())
to get an interactive variant of the DOM node that is the root of your component in the dev tools console.
The tool you mentioned, do you have the intention to keep it internally? Thanks @oderwat
This is not planned. First of: Releasing anything usually means that you need to support and fully document it. We are too small to handle that. Second: This is magic and the tools name is even magx
and therefor it is also dangerous to use. It even contains the line "Preventing you from imploding the universe" as one of its error messages.
You should maybe check out "mage" which was used by us in the past and where I wrote the first automatic re-compiler for. I think https://github.com/oderwat/go-nats-app could be of interest for you (maybe also for the front-/backend communication for which we use NATS nearly exclusively). The actual watcher code could be a variant of run which starts the program in a go routine and then polls the glob patterns for changes, if they occur you kill the process and start over again. Of course there are multiple other things to be taken care of. I once used some other go based file watcher but I don't remember which one and why it was not "good enough" in the end.
from go-app.
Hi, cool that you try go-app :)
The problem with your code is that you missed that app.Route()
gets an example of the components type and not an initialized component. You need to add your data inside of the components OnMount()
or OnInit()
.
from go-app.
Thanks @oderwat
Now I am getting the expected result:
I have changed my code as below, but I still can't understand why I am getting the following log message while entering Render function:
msg=len(sc.Students) !BADKEY=0
it seems the Compo is not initialized yet.
code:
package main
import (
"fmt"
"time"
"os"
"log/slog"
"net/http"
"github.com/jszwec/csvutil"
"github.com/maxence-charriere/go-app/v9/pkg/app"
)
type Student struct {
Name string `csv:"name"`
Age int `csv:"age,omitempty"`
CreatedAt time.Time
}
type StudentCompo struct {
app.Compo
Students []Student
}
func (sc *StudentCompo) Render() app.UI {
slog.Info("StudentCompo Render called")
l := len(sc.Students)
slog.Info("len(sc.Students)", l)
for i:=0; i<len(sc.Students); i++ {
slog.Info("Name", sc.Students[i].Name)
slog.Info("Age", sc.Students[i].Age)
slog.Info("CreatedAt", sc.Students[i].CreatedAt)
}
return app.Div().Body(
app.Table().Body(
app.Tr().Body(
app.Th().Text("Name"),
app.Th().Text("Age"),
app.Th().Text("CreatedAt"),
),
app.Range(sc.Students).Slice(func(i int) app.UI {
return app.Tr().Body(app.Td().Text(sc.Students[i].Name),
app.Td().Text(fmt.Sprintf("%d", sc.Students[i].Age)),
app.Td().Text(sc.Students[i].CreatedAt.Format(time.RFC3339)),
)
}),
),
)
}
func (sc *StudentCompo) OnMount(ctx app.Context) {
slog.Info("StudentCompo OnMount called")
sc.Students = createStudents()
}
func createStudents() []Student {
slog.Info("createStudents called")
var csvInput = []byte(`
name,age,CreatedAt
jacek,23,2012-04-01T15:00:00Z
john,21,2001-05-21T16:57:00Z`,
)
var students []Student
if err := csvutil.Unmarshal(csvInput, &students); err != nil {
fmt.Println("error:", err)
}
return students
}
func main() {
logLevel := new(slog.LevelVar)
logLevel.Set(slog.LevelInfo)
logger := slog.New(slog.NewTextHandler(os.Stdout, &slog.HandlerOptions{Level: logLevel}))
slog.SetDefault(logger)
slog.Info("Student component starting")
app.Route("/", &StudentCompo{})
app.RunWhenOnBrowser()
http.Handle("/", &app.Handler{
Name: "Student",
})
if err := http.ListenAndServe(":3000", nil); err != nil {
slog.Info("ListenAndServe:", err)
}
}
Do you have any plan to extend your library with more standard components?
from go-app.
Render()
is called before OnMount()
because the "mounting" creates the node so if you need to initialize a structure you should use OnInit()
or make Render()
work with the non initialized state. if !sc.Mounted()
would be a universal way to do that. I prefer to check my data and react properly on it's state though.
I see you use slog
and that is great, but I think for the front end you should Go with app.Log()
or use what we use all the time dbg.Log()
(from https://github.com/metatexx/go-app-pkgs/) because this shows you source and line for the callers, which makes it much easier to debug in the frontend as there is not yet a lot of other debugging help available. dbg.Logc()
can also help a lot because it lets you easily dump JSValue
in a way that you can use the developer tools to browse through the dump. app.Logf("%v") / dbg.Logf("%v")
will only print the Go wrapper types instead.
from go-app.
It works @oderwat .
Thanks .
I am still reading the documentation but it is not clear to me if Render() can be nested. Suppose I have a bar-menu a top-menu and body, how should I declare these objects?
from go-app.
You place one component into another one. The only limitation with that is, that each component must have a root component. So if you had one that are table rows, you need to have the '' as their parent to make it a component that then can co into a <table><thead><tr><td>A</td><td>B</td></tr></head>{component:<body><tr><td>A</td><td>B</td></tr></thbody>}</table>
construct (using {} to illustrate the component, and it's Render()
output).
We usually place each component in its own package to avoid directly shared data.
from go-app.
Thanks @oderwat .
I am not very confident with WASM. How debug is possible in SPA? I can't see the effect of my changes in the source page so is there any other way to check if my code is correct?
from go-app.
You can write tests (see go-app test sources). You can actually debug in the browser, but that is not expressive, but I think they work in it. But currently you mostly need to do "app.Log()" or "dbg.Log()" (our package) print debugging.
For the problem with recompilation and reloading I wrote an internal tool that for all our go applications including the PWAs handles restarts of services and apps with support for go.work files and other stuff. But that comes down to simply checking for changes and restarting the app server and have a short time update checker in the web application and have that reload. There one "can" store state in local storage and let the app jump into this, so that you do not have to click through all the functionality. You could also write short individual applications that test / demos components. We do this by the same tool which also does the watcher functionality as this can create an app skeleton by just giving it a name.
Besides all of this I also experimented in automatic testing through headless chrome witch also works quite well, but we do not utilize that in production yet. I have an older public repo with a proof of concept. We (again internally) have a larger testing framework build on this idea. https://github.com/oderwat/rodgoapp
from go-app.
Could you please make an example of using app.Log() or dbg.Log() ?
The tool you mentioned, do you have the intention to keep it internally?
Thanks @oderwat
from go-app.
Also PreRender can be useful for debugging?
from go-app.
Also PreRender can be useful for debugging?
We actually never use PreRender()
at all. Because of the code separation of WASM and server code there is not even any of the component in the server and therefor there are other routes and there is just one empty component. You can see this in https://github.com/oderwat/go-nats-app/blob/master/backend-entry.go
from go-app.
For debugging the actual WASM I found some good information here:
https://www.youtube.com/watch?v=DcEcRfauvuw
https://github.com/WebAssembly/wabt
from go-app.
Render()
is called beforeOnMount()
because the "mounting" creates the node so if you need to initialize a structure you should useOnInit()
or makeRender()
work with the non initialized state.if !sc.Mounted()
would be a universal way to do that. I prefer to check my data and react properly on it's state though.I see you use
slog
and that is great, but I think for the front end you should Go withapp.Log()
or use what we use all the timedbg.Log()
(from https://github.com/metatexx/go-app-pkgs/) because this shows you source and line for the callers, which makes it much easier to debug in the frontend as there is not yet a lot of other debugging help available.dbg.Logc()
can also help a lot because it lets you easily dumpJSValue
in a way that you can use the developer tools to browse through the dump.app.Logf("%v") / dbg.Logf("%v")
will only print the Go wrapper types instead.
Mhh, OnInit()
is a thing? I don't see it being referenced there: https://go-app.dev/components#lifecycle-events
from go-app.
Mhh,
OnInit()
is a thing? I don't see it being referenced there: https://go-app.dev/components#lifecycle-events
I think that whole diagram is a bit outdated or does not contain the information that is needed (imho). OnInit()
was proposed by me quite some time ago and the graphics also does not mention render at all. I guess that the v10 release also makes changes to order and details of the execution and that @maxence-charriere updates the documentation eventually.
from go-app.
Documentation will be revamped. At the begining v10 changed some stuff in terms of ordering but is has been reverted back since you folks were using those things.
from go-app.
Ok 👌🏻
from go-app.
I'm really struggling to deploy my website too, I hope the new doc will improve this part. I tried the static way showed in the current doc but half of my website is broken doing this way. I'm still a bit confused what goes into the "static" part.
Everything works fine if I launch a web server on "/" but doing this way I struggle to deploy it on services such as fly.io.
from go-app.
Related Issues (20)
- How to force ctx.Navigate() to open target in a new Tab HOT 1
- I think there is serious bug with `ctx.PreventUpdate()` now HOT 5
- Unable to set css class for svg custom elements HOT 1
- Is go-app still an active project? HOT 5
- Is this dead? HOT 10
- Load static files to Canvas HOT 2
- Support for React? HOT 3
- Global css variables does not get set HOT 3
- New name for go-app? HOT 1
- V10 property update issue HOT 3
- Makes the generated HTML available without having to mount the elements. HOT 2
- Modify tag building so that we can avoid calling Body() HOT 4
- Signal based change detection HOT 2
- Render calls before OnMount HOT 1
- debug go-app in nowasm HOT 4
- tiny hamburger on mobile HOT 5
- Hot Reload HOT 2
- Issue Cleanup and Focus for Go-app v10
- Route regex like containing `?param=` is not routing HOT 21
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from go-app.