starcounter / helloworld Goto Github PK
View Code? Open in Web Editor NEWSample Starcounter application that shows CRUD operations with Palindrom (HTML+JSON-Patch client)
Sample Starcounter application that shows CRUD operations with Palindrom (HTML+JSON-Patch client)
@Mackiovello what do you think about this:
At the end of each step in the tutorial text, add link to this repository with information about how to checkout the code for this specific step.
We got this comment to a commit from @alshakero (source):
public string FullName => FirstName + " " + LastName;
@warpech this won't compile on VS2012 .NET 4.5. I had to change it into an old-fashioned getter
public string FullName { get { return FirstName + " " + LastName; } }
It would be great to make our sample apps compile in all supported versions of VS without sacrificing the usage of C# 6.0.
@alshakero could you please check if installing C# 6.0 with these instructions http://stackoverflow.com/questions/28638547/c-sharp-6-0-support-in-visual-studio-2012 solves the problem?
As proposed by @miyconst in f9c38a2#commitcomment-17462738
On the page "First Interactive UI" there is a paragraph that advocates the use of server-side view-models in a quite unconvincing way.
This was reported by Ted.
I propose to rewrite this paragraph:
Notice here that our application logic is written in the code-behind and not in the view. The purpose of that is to completely remove the need to write so-called “glue code” that otherwise would translate changes between the view, view-model, and model. The benefits of this are many. For this tutorial, we will not focus further on that topic, instead, we just have to remember that all our application logic should be written in the code-behind.
With something like:
With server-side view-models you don't have to write a single line of "glue code" to update the view in HTML. Any change in the view-model made in C# will be automatically propagated to the client by PuppetJs, which in turn automatically renders thanks to Polymer's data binding. This saves you from creating single-purpose REST APIs, need for double validation of user input, etc.
Good to put some link in the right column that explains this in details.
The current title of step 7 "Simplifying the Data Model" misses the point of this step.
The point is to switch from your own data model to a shared data model, so you can benefit from your data being shared with other apps.
I propose to rename this step to "Using a shared data model"
Recently in the images app the URI that shows an Image of a something was changed.
In Step 9 (mapper apps), the line:
return Self.GET("/images/partials/concept/" + objectId);
needs to be changed to:
return Self.GET("/images/partials/somethings-edit/" + objectId);
Actually /images/partials/somethings-edit/
displays a carousel with multiple items. It would be enough to have /images/partials/somethings-single-edit/
, but we don't have that in the Images app now.
Update HelloWorld to use the "XxxxTrigger$" pattern in JSON.
Relevant file: https://github.com/StarcounterApps/HelloWorld/blob/tutorial-20161222/src/HelloWorld/PersonJson.json
Properties: Save$
, Cancel$
, DeleteAll$
Discussion here: Starcounter/Guidelines#12
Definitely some introduction before "Part 1" is needed. Looking forward to see it when it's done. This might be done as a separate article or as few paragraphs of introduction in the same paragraph.
I would rename this section from "Initialize the Database" to "Create a database class".
Establish a new class Person with the attribute [Database] inside the HelloWorld namespace.
After this sentence, I propose to write something like "This tells Starcounter to make any instance of this class persistent."
"which will push this person into the database"
Change to "which will keep this person in the database".
Add a screenshot or animated GIF of using SQL in Administrator.
On this page http://starcounter.io/tutorials/hello-world/ui-blending-hello-world-part-9/
add a "read more" link to this page: http://starcounter.io/guides/web/import-html-compositions/
Thanks!
Once I have added some expenses to http://localhost:8080/HelloWorld (step 6) and reload the page, my expenses are no longer there.
Is it a "know simplification" not to write too much code?
If so, I find it pretty confusing as even though there are no expenses my balance is >0, and they will appear after clicking "Cancel" button.
I think that the PersonJson.json
snippet should include the curly braces.
The ::input syntax is similar to an event listener. It registers every time there is a new input and updates the JSON accordingly.
I would change it to: The ::input
declaration sets up an event listener. It updates the JSON as you type in the HTML input element.
trigger an handler
"trigger a handler"
Open your application by pressing F5and clicking open in the Starcounter Administrator.
I think that this should be exactly the same info as in "Step 2".
Try hitting save and then check out your database with SQL.
I like this! I think this should be a separate paragraph though, with a screenshot or animated GIF.
As Ted pointed out, the "Create a Real Time UI" jumps to creating files without explaining what we are really doing:
It’s not clear what these files are for at the beginning; can you at least give me a hint as to why these files will be necessary? That way I’m at least thinking about it while I follow your steps to create them. Also, in this file, you mention Polymer, but I don’t think it’s mentioned anywhere before this—I didn’t realize that was in play until just now.
I think that we need to explain in one paragraph that we are defining a view-model in C# with a real time view in HTML.
Some description might be borrowed from:
Question.
At the moment, when an image is clicked, it changes the page to the image.
Would it perhaps be better to make the image open on a separate tab?
@Mackiovello @warpech what do you guys think?
I need help to figure out a problem in the last step of Hello World.
There is a Cancel
button that rolls back a transaction. It fails two work in two cases. Case 1:
http://localhost:8080/helloworld
Case 2:
http://localhost:8080/helloworld
@miyconst any idea how to solve this elegantly?
As proposed my @miyconst in 415afc6#commitcomment-17462712
Release a new version based on the changes made while preparing for InfoShare 2016: https://github.com/StarcounterSamples/HelloWorld/commits/SimplerMiddlerwareStaticPage
If somebody finds the repo first, make it trivial for them to get to the tutorial itself—put a link in there, or else have the steps summarized in the README.
Some tiny inspiration can be taken from how it is done in https://github.com/Starcounter/InvoiceDemo/blob/master/README.md
Got this suggestion from Ted.
As the last step (7), it should be possible to add an image of the expense instead of text description.
The image should be added using the Images app.
Can we take a step back, to a more high-level view?
Here's a discussion I'd like to have, and I'm using #6 (HelloWorld
+ Images
) as the context, but it should apply to any kind of app inter operable scenario.
I'm the developer of Hello World
. I've completed it up to step 6 in the tutorial. By chance, I find the Images
app in an app store. I try it out, and find that it should be nice to support images to be attached to expenses.
What's our story here? What's needed, and by whom - can I complete everything by reusing a certain partial of Images
, and if so, what info would I need? It's URI pattern? Would there have to be any mapping made inside the Images
app (I hope and think not).
What changes if Images
is open/closed source? What changes if it builds upon Simplified
compared to if it employs it's local model?
I guess this topic is not something easily answered simply, but let's see if we can get something out of it at least.
@Mackiovello do you think it would be a good idea to add build.bat
, run.bat
in HelloWorld?
For me this would surely make it easier to run. I think it could be added in commit of Step 1 without even mentioning it in the Tutorials.
As proposed by @miyconst in f9c38a2#commitcomment-17462723
You did your best in writing this page, but actually I admit that I chose only one of the possible ways to do the blending in my code.
Actually it is possible to use a completely different method of setting up the blended UI:
[partial-id="/sc/htmlmerger?HelloWorld=/HelloWorld/ExpenseJson.html&Images=/Images/viewmodels/ConceptPage.html"]
from the listThe method that I describe above is possible to do by point-and-click in runtime, as opposed to the current method that requires Git Bash and cURL.
Which is better? I don't know, perhaps both should be presented in the tutorial?
Maybe let's add a brief introduction in the beginning? Something along the lines of:
Let's practice working on multiple object instances and relations. We will turn our app into a simple expense tracker. We will learn how to compose a complex view using multiple small partial views.
Regarding the list of steps:
- Add a new Starcounter HTML template with dom-bind in the HelloWorld folder together with PersonJson.html.
- Add a new Starcounter Typed JSON with Code-behind file to the HelloWorld project together with PersonJson.json and PersonJson.json.cs.
- Name all of these files ExpenseJson.
I think this will be better:
ExpenseJson.html
.ExpenseJson.json
.starcounter-include is basically a placeholder for another template
I would prefer: starcounter-include
is an insertion point for another template
We will also add using System and using System.Collections.Generic at the same time.
This does not make sense here. Actually it also does not make sense in the program (my bad). It must be some artifact from previous versions. Let's remove using System
and using System.Collections.Generic
from the program and from the tutorial text.
Would like to add info windows or pop-ups to the code similar to what's on Angular's guide.
The issue is that every WordPress plugin and even the built in fusion shortcode by the theme messes with the code block so that all the remaining code on the line gets marked as a comment. Like this:
It also destroys the indentation on the whole page.
Angular uses something like code-prettify which might interact differently with inserts into code.
To make Polymer work.
I propose to change it to: "To make use of Polymer's template engine"
previously empty json file
Change to "previously empty JSON file"
Start the application with F5 and open the HelloWorld file in localhost:8181/#/databases/default. You should see the name of your Person appear.
I think that there is a simpler way. "Start the application with F5 and go to http://localhost:8080/HelloWorld in your web browser. You should see the name of your Person appear."
Let's try to use HelloWorld as a playground to investigate bridging PuppetJs with Polymer 2.0 (instead of 1.x).
@alshakero please take this and see how far we can get.
In: https://starcounter.io/hello-world/create-a-database-class-hello-world-part-1/
Create a Database Class
Create a folder named src inside the HelloWorld solution. Drag the HelloWorld project into this folder. We will later add another project, so this makes it easier for us to organize.
How?
How to: Add Solution Folders to a Solution document describe as;
In Solution Explorer, right-click the solution or a Solution Folder, choose Add, and then choose New Solution Folder.
But it does not create windows folder! But your source have src folder.
Solution Folders are an organizational tool in Solution Explorer; corresponding Windows folders are not created. We recommend that you organize your projects on disk in the same way that you organize them in the solution.
I think, i missed something.
I think that "Computed properties" would be a better name for this page.
Right now, our application does not display the name as we type. Would it not be better to let the code-behind calculate the full name and then display that to the user without any delay? Let us do that!
I think that this introduction misses some of the key benefits. I propose to rewrite it:
"Starcounter allows you to use computed properties in your data model. Computing values on the fly is often as fast as accessing cached data and brings additional benefits. It allows you to save memory and always be sure that you get the current value.
Let's compute the FullName
of a person from their FirstName
and LastName
and display it without any delay!"
concatenating together
"concatenating"
Our next step is to add an expense tracker. That will take a little more effort.
I propose: "Our next step is to practice working on multiple object instances and relations. We will turn our app into a simple expense tracker."
In step 9 you are supposed to either use a curl command or the built-in layout editor. Because of the broken layout editor with a non-editable input screen and disabled buttons, you cannot use it.
Is there a simple way of working around this as this seems to be the most accessible way of doing it?
Steps to reproduce:
Starcounter.DbException: ScErrSchemaCodeMismatch (SCERR4177): Operation failed because input does not match schema. CLR Class is not loaded for table HelloWorld.Spender
Version: 2.3.0.6120.
Help page: https://github.com/Starcounter/Starcounter/wiki/SCERR4177.
at Starcounter.Binding.Bindings.CreateExceptionOnTypeDefNotFound(Int32 tableId) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Binding\Bindings.cs:line 485
at Starcounter.Binding.Bindings.BuildTypeBindingFromTypeDef(Int32 tableId) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Binding\Bindings.cs:line 353
at Starcounter.Enumerator.MoveNext() in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Mock\Enumerator.cs:line 239
at Starcounter.Query.Execution.FullTableScan.MoveNext() in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Query\Execution\Enumerators\FullTableScan.cs:line 479
at Starcounter.Query.Execution.Sort.CreateEnumerator() in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Query\Execution\Enumerators\Sort.cs:line 115
at Starcounter.Query.Execution.Sort.MoveNext() in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter\Query\Execution\Enumerators\Sort.cs:line 145
at Starcounter.Json.Array_InitializeAfterImplicitConversion(Json parent, TObjArr template) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.XSON\Class Json\Json.Array.cs:line 79
at Starcounter.Templates.TArray`1.BoundOrUnboundSet(Json parent, Arr`1 value) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.XSON\Templates\TArray.cs:line 119
at People.PersonsPage.set_Persons(Arr`1 value) in c:\www\People\src\People\obj\x64\Debug\ViewModels\ViewModels\PersonsPage.json:line 20
at People.PersonsPage.RefreshPersons() in c:\www\People\src\People\ViewModels\PersonsPage.json.cs:line 20
at People.PartialHandlers.<>c.<Register>b__0_1() in c:\www\People\src\People\Api\PartialHandlers.cs:line 39
at Starcounter.Rest.UserHandlerInfo.RunUserDelegate(Request req, IntPtr methodSpaceUriSpaceOnStack, IntPtr parametersInfoOnStack) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Rest\UriHandlersManager.cs:line 341
at Starcounter.Internal.Web.AppRestServer.RunDelegateAndProcessResponse(IntPtr methodSpaceUriSpaceOnStack, IntPtr parametersInfoOnStack, Request req) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Apps.JsonPatch\AppRestServer.cs:line 98
at Starcounter.Rest.UriManagedHandlersCodegen.RunUriMatcherAndCallHandler(String methodSpaceUriSpace, String methodSpaceUriSpaceLower, Request req, UInt16 portNumber, Response& resp) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Rest\UriManagedHandlersCodegen.cs:line 1133
at Starcounter.Self.DoSelfCall(UInt16 portNumber, String method, String relativeUri, Dictionary`2 headersDictionary, String body, Byte[] bodyBytes, HandlerOptions handlerOptions, Request req) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Internal\Rest\Self.cs:line 397
at Starcounter.Self.GET[T](String uri, HandlerOptions ho) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Internal\Rest\Self.cs:line 22
at People.MainHandlers.GetLauncherPage(String Url, Boolean DbScope) in c:\www\People\src\People\Api\MainHandlers.cs:line 138
at People.MainHandlers.<>c.<Register>b__0_5() in c:\www\People\src\People\Api\MainHandlers.cs:line 65
at People.AuthorizedHandle.<>c__DisplayClass0_0.<GET>b__1() in c:\www\People\src\People\Helpers\AuthorizedHandle.cs:line 9
at People.AuthorizedHandle.TrySignIn(Func`1 code) in c:\www\People\src\People\Helpers\AuthorizedHandle.cs:line 21
at People.AuthorizedHandle.<>c__DisplayClass0_0.<GET>b__0() in c:\www\People\src\People\Helpers\AuthorizedHandle.cs:line 9
at Starcounter.Rest.UserHandlerInfo.RunUserDelegate(Request req, IntPtr methodSpaceUriSpaceOnStack, IntPtr parametersInfoOnStack) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Rest\UriHandlersManager.cs:line 341
at Starcounter.Internal.Web.AppRestServer.RunDelegateAndProcessResponse(IntPtr methodSpaceUriSpaceOnStack, IntPtr parametersInfoOnStack, Request req) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Apps.JsonPatch\AppRestServer.cs:line 98
at Starcounter.Internal.AppsBootstrapper.ProcessExternalRequest(Request req) in C:\TeamCity\BuildAgent\work\sc-4133\Level1\src\Starcounter.Apps.JsonPatch\AppsBootstrapper.cs:line 765
ErrorCode=4177
HResult=-2146233088
HelpLink=https://github.com/Starcounter/Starcounter/wiki/SCERR4177
More information about this error may be available in the server error log.
As @mtornwall pointed out in https://github.com/Starcounter/CompanyTrack/issues/242#issuecomment-256587065, Steps 8 and 9 are using an approach that is likely to be changed in future.
I think that we owe it to the developer to explain this. Something along the lines of:
The APIs presented on this page are experimental. Blending of apps' user interfaces is an essential feature of Starcounter, but the way to achieve it is likely to be changed in future. Please follow our blog to learn more.
@Mackiovello can you add the above notice to Steps 8 and 9? Feel free to improve the message.
Right now the code blocks are described by the file they're in.
We should add an additional snippet of text on the same row of the file name that describes the code-block.
Suggestion - I think that two code snippets in Step 1 are a little bit too shortened.
The first code snippet should look like:
using Starcounter;
namespace HelloWorld
{
[Database]
public class Person
{
public string FirstName;
public string LastName;
}
class Program
{
static void Main()
{
}
}
}
The second snippet should be:
class Program
{
static void Main()
{
Db.Transact(() =>
{
var anyone = Db.SQL<Person>("SELECT p FROM Person p").First;
if (anyone == null)
{
new Person
{
FirstName = "John",
LastName = "Doe"
};
}
});
}
}
Right now it is:
I propose to rename this page to "Use a shared data model"
Currently, we define every attribute of our database classes. That is a waste. C# is an object-oriented language, so we can inherit the needed attributes from an already defined database class. Starcounter has provided a tool for that called Simplified. To get this data model into our program we need to take two steps:
This is interesting to see your introduction to the page. But it misses the most important reason. I propose to rewrite the above paragraph to be:
"In the previous steps, we have used a data model declared using [Database]
classes directly in Program.cs
. This is nice for prototyping, but does not get us very far in terms of code and data reuse.
Starcounter has a unique ability to allow multiple apps to work on the same data. We do this by putting the data model into a separate project and loading it as a DLL in all apps that are interested.
It is also possible to map two unrelated data models, but this Tutorial does not cover that.
Starcounter comes with a built in data model called "Simplified". Using it or inheriting from it allows you to integrate your apps with our sample and prefab apps, without extensive data mapping."
Every page in the Hello World tutorial should consistently finish with <section class="see-yourself">
section, followed by a screenshot/GIF.
Currently, only some pages have "see yourself" sections and only some have screenshots.
@Mackiovello I don't know if you know, animated GIFs can be easily created using LICEcap.
To back up the written tutorials I'll make video tutorials for those that prefer watching instead of reading. The code will be the same, although the content might be a little bit more in-depth in the videos. The goal is to keep them below 10 minutes.
The steps to achieve this are:
My proposed timeline is to have all the videos done by January 7th.
Part one has been recorded and reviewed by @ubbeK. It will be remade with better sound equipment once the pop-filter arrives.
Are there any suggestions to keep in mind?
Progress tracker:
This is an issue for investigation. What does it take to rebuild Hello World using React instead of Polymer on the client side. The solution should still use PuppetJs, so a PuppetJs-React bridge will be needed.
@alshakero - can you take this as a long term investigation? Please don't focus too much on it right now, but investigate when there are no other more important issues.
In future, I would also love to see a combination of Vue.js and PuppetJs.
an external app called Images
"an prefab app called Images"
from github
"from GitHub"
In addition, you have to add using Starcounter.Internal to the beginning of the same file.
To set up mapping for the "Images" app, you have to declare the code in context of that app using StarcounterEnvironment.RunWithinApplication
. This method becomes available after adding using Starcounter.Internal
to the beginning of the file.
Suggestion: allow me to do so, and treat that as 0.
When you download HelloWorld from GitHub, open in VS and press debug, there is a message saying that the binary file is not found.
This is because the solution is not configured to automatically build when debugging.
I have a fix locally and can submit it.
cc @Mackiovello
<template>
<div class="example">{{ msg }}</div>
</template>
<script>
export default {
data () {
return {
msg: 'Hello world!'
}
}
}
</script>
<style>
.example {
font-weight: bold;
}
</style>
This paragraph feels a little odd:
This is not your ordinary Hello World tutorial. Instead of only checking whether your setup is correct, as the goal with other Hello World tutorials usually is, we will also help you to understand Starcounter’s features and how it can help you as a developer to create fast, modular applications in a fraction of the time it would usually take.
We will guide you through the process of creating a database, making an interactive UI, and blending different applications seamlessly together.
As suggested by Ted, it could be rewritten to sound more appealing.
I like how this tutorial begins: https://spatialos.improbable.io/docs/reference/8.0/tutorials/pirates/overview
As due to https://github.com/Starcounter/Starcounter/issues/3915 Launcher needs to be running to execute the curl with layouts, I think it would be good to mention this at
d511f5a#diff-0cbf7f0b9cd8fbd93b45f23f30787aa1R10
As I spent almost an hour wondering why I get
URI not found: POST /sc/partial/composition?key=%2Fsc%2Fhtmlmerger%3FHelloWorld%3D%2FHelloWorld%2FExpenseJson.html%26Images%3D%2FImages%2Fviewmodels%2FConceptPage.html&ver=
Perhaps it would be good to rename the URL from "Hello World Introduction"?
Some suggestions:
WDYT?
Also, I recommend to change the URL from http://starcounter.io/tutorials/hello-world-introduction-2/
to http://starcounter.io/tutorials/hello-world/
Application.Current.Use(new PartialToStandaloneHtmlProvider()); sends the necessary files to inititate our WebSocket connection.
Is it?
or
If firstPage does not contain <!DOCTYPE html>
, Starcounter sends implicit HTML template that contains code to bootstrap.
<!DOCTYPE html>
<html>
<head>
....bootstrap.....
</head>
<body>
--->> firstPage
</body>
</html>
Gif's does currently only work in some browsers if you open them up in full screen.
Try to find a solution where the GIF's play automatically without needing to click on them.
Yeah yeah I know we've been discussing this in iterations again and again, and I do not discover anything new there, and this is not about a particular tutorial but the problem in general, but we really need to continue actively thinking until the problem is resolved. Step 1 in tutorial is supernice and simple with db classes and transaction, but then Step 2 "Adding some Gui" is like "BOOOOF" in my face:
Application.Current.Use(new HtmlFromJsonProvider());
Application.Current.Use(new PartialToStandaloneHtmlProvider());
Handle.GET("/HelloWorld", () => {
var json = new PersonJson();
json.Data = Db.SQL<Person>("SELECT p FROM Person p WHERE p.LastName = ?", "Doe").First;
json.Session = new Session(SessionOptions.PatchVersioning);
I could never understand libraries and frameworks where complexity is "end in itself" (maybe they are so beloved because they create so many wonderful jobs to tackle this complexity). Unfortunately this is the impression I get from .Use
and explicit session creation.
I believe the problem is more generic there - i.e. the problem is how to make managing the session (shared state and transaction) really simple, straightforward, magic-less. The feeling is partially because names are way too verbose, but also because the session and "app" itself feels like something "added afterwards", not-so-native.
I already had this analogy. When I go to a new restaurant, I wish to get "Chef Recommends" meal, because I don't want to study pages of menu and make choice myself. I am tired in the evening and just want to relax with a glass of wine enjoying chefs best choice. It doesn't mean that I cannot ask chef to not use sauce - in fact it should be possible. But then they tell me "No, you should do all the choices yourself, spend next 3 hours studying menu and ingredients, all for you man, we know you'd manage to cope with it, you are strong fella", something like that (the picture is called "A cake for Linux' birthday"):
Do you share my feeling? :)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.