Giter VIP home page Giter VIP logo

dotnetify's Introduction

alt build npm version NuGet

DotNetify is a free, open source project that lets you create real-time, reactive, cross-platform apps with React, React Native, Vue, Knockout or Blazor front-end on C# .NET back-end via WebSocket (SignalR or Amazon API Gateway).

What's New

DotNetify.Postgres: Real-time Web Updates From Your PostgreSQL Database

Features

  • Simple and lightweight - no heavy client-side framework, no REST APIs.
  • Reactive back-end MVVM architecture on ASP.NET server.
  • Built-in real-time across WebSocket with either SignalR or Amazon API Gateway.
  • Support local (client-side only) and Web API modes.
  • Full support for single-page apps, including deep-linked, nested routing and token-based authentication.
  • Powerful back-end infrastructure, including dependency injection, WebSocket request/response pipelines, and modern tooling.

Premium Features

Documentation

Documentation and live demo can be found at https://dotnetify.net.

Code Examples

License

Licensed under the Apache License, Version 2.0.

Contributing

All contribution is welcome: star this project, let others know about it, report issues, submit pull requests!

Logo design by area55git.

dotnetify's People

Contributors

bajakigabesz avatar dependabot[bot] avatar dsuryd avatar hengzheli avatar koriseng avatar lilasquared avatar mason-chase avatar mrfoxpro avatar nimashoghi avatar thomasmerant avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

dotnetify's Issues

local sort

Hi Dicky,

Season's greetings !

I am trying to implement the local sort as shown in your gridview example.
Instead of Employees property, my property name is potran_list
Inside the $preventBinding function, I am getting the following error
IE - object does not support propery or method - sort
Chrome - vm.potran_list.sort is not a function

What am I doing wrong?

Thanks
Ajit

Bind to Subclass

Is it possible to bind to a subclass?
I would like to create a base class for my pages as they all have some basic features.

I tried something like this:

public class PageBase : BaseVM, IRoutable

public class Page1 : PageBase

Unfortionatly it doesn't seem to work when I bind to Page1. Is dotnetify only looking for classes which are directly based on "BaseVM"?

Data bind to a date field

What is the best way to bind to a date?

First line works perfectly without data binding, the second is receiving:

The specified value "1975-01-13T00:00:00" does not conform to the required format, "yyyy-MM-dd".

                                @Html.TextBoxFor(model => model.ActiveOccupant.DateOfBirth, "{0:yyyy-MM-dd}", new { type = "date", @class = "form-control" })
                                @Html.TextBoxFor(model => model.ActiveOccupant.DateOfBirth, "{0:yyyy-MM-dd}", new { type = "date", @class = "form-control", data_bind = "value: ActiveOccupant.DateOfBirth" })

Unable to use websockets

If I follow the instructions in the help I end up getting the following exception if I try to use websockets from the client. Long-polling works...

System.Resources.MissingManifestResourceException: Could not find any resources appropriate for the specified culture or the neutral culture. Make sure "Microsoft.AspNetCore.SignalR.Server.Resources.resources" was correctly embedded or linked into assembly "Gray.Microsoft.AspNetCore.SignalR.Server" at compile time, or that all the satellite assemblies required are loadable and fully signed.

Reactive Extensions support?

Hi! Great project!

I want to develop a project using dotNetify but I want to know if there is support for Reactive extensions.

Connect

You write :

When the connection is established, the class instance will be serialized to JSON and sent as the initial state for the component.

But in the examples in the getInitialSate you are returning an empty state right after the connect - it works obviously but doesn't make sense to me.

VM being disposed early

Hi, great library, really enjoying the simplification it provides.

However it's not clear to me what manages the lifetimes of the VMs. I am instantiating a long-lived calculation engine in my VM, and I need it to stay alive for the duration of a connection from a browser. However it seems to be getting disposed at apparently random times after a bit of inactivity.

What can make it dispose other than a call to vm.$dispose() [ which I have in componentWillUnmount, but that's not where it's coming from]

Using dotnetify 2.0.4beta with react 15.5.4

Thanks.

WebSocket server-side management

@dsuryd: Thank you for all of your excellent work.

We are working on chat-like funtionality (actually: sending transaction states and other business events to clients). Before stumbling upon dotNetify, I was exploring https://chsakell.com/2016/10/10/real-time-applications-using-asp-net-core-signalr-angular/ , which has a Chat example. The source and blog of chsakell is very good and also usable as a starting point for us, but your dotNetify architecture has an ever greater appeal to me. Especially the React integration, but also the end product: the Angular example of chsakell has to be optimized to be usable from mobile (mainly angular4 seems to make the UX feel very bloated and slow, although I didn't try minimizing/uglifying yet), and your examples work amazingly smooth.

You advice please: When implementing a chat example in dotNetify, should I dive into dotNetify's internals, or should I setup a concurrent websocket route, separate from dotNetify with more control over what happens?

Communication between viewmodels

Hi, congratulations for this project !

I want to add communication between viewmodels without event (like mvvmlight messenger).
I've implemeted a solution and I would like your opinion.

The main principles are :
When I publish a notification of type T where T : IVMNotification, all actives VMs that implents IHandleVMNotification are notified.

public class AppVM : BaseVM, IRoutable, IHandleVMNotification<ShowMessageRequested>
{ ....
    public void Handle(ShowMessageRequested notification)
    {....}
}

I use MediatR to publish/handle notifications.

vm can publish notification with mediator instance injected from the constructor.

    public class BaseMediatrVM : BaseVM
    {
        private readonly IMediator _mediator;
        ...

        public BaseMediatrVM(IMediator mediator)
        {
            _mediator = mediator ?? throw new ArgumentNullException(nameof(mediator));
        }

        protected void Publish(VMNotificationBase notification)
        {
         ...
            _mediator.Publish(notification);
        }
    }

    public class HelloWorldVM : BaseMediatrVM, IHelloWorldState
    {
        ...
        public string Greetings
        {
            get => Get<string>();
            protected set
            {
                Set(value);
                Publish(new ShowMessageRequested(value));
            }
        }

        public HelloWorldVM(IMediator mediator):base(mediator)
        {
          ...
        }
        ...
    }

Then my handler of type MediatR.INotificationHandler handle the notification.

Here begins questions ! :)
The idee is to broadcast the notification by using DotNetify.IVMControllerFactory injected from the handler's constructor.

DotNetify.IVMControllerFactory call the good VMController
The VMController broadcast the notification to actives VM interested by the message

First problem, I need to have the SignalR connectionId to be able to get the good VMController.

To solve that, I've added ContextKey property to VMBase

        /// <summary>
        /// The key of the vmController parent
        /// </summary>
        [Ignore]
        public virtual string ContextKey { get; set; }

and set the value in VMController.CreateVM(...). Now I can publish notification containing the ContextKey.

My final VMController :

     /// <summary>
    /// This class manages instantiations and updates of view models as requested by browser clients.
    /// </summary>
    public class VMControllerWithNotificationBroadcast : VMController    {

        /// <summary>
        /// Constructor.
        /// </summary>
        /// <param name="vmResponse">Function invoked by the view model to provide response back to the client.</param>
        /// <param name="key">Identifies the object.</param>
        public VMControllerWithNotificationBroadcast(VMResponseDelegate vmResponse, string key):base(vmResponse,key){ }
        
        /// <summary>
        /// Creates a view model.
        /// </summary>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="vmArg">Optional view model's initialization argument.</param>
        /// <returns>View model instance.</returns>
        protected override BaseVM CreateVM(string vmId, object vmArg = null)
        {
            var vmInstance = base.CreateVM(vmId, vmArg);
            vmInstance.ContextKey = _key;

            return vmInstance;
        }

        /// <summary>
        /// Broadcast the notification to all the concerned actives vm.
        /// </summary>
        /// <typeparam name="T">Type of the notification to broadcast</typeparam>
        /// <param name="notification">The notification to broadcast</param>
        public void BroadcastNotification<T>(Notification.IVMNotification notification) where T : Notification.IVMNotification
        {
            foreach (var item in GetActiveVMsOfType<Notification.IHandleVMNotification<T>>())
                item.Handle((T)notification);
        }

        /// return all actives VM of type T
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        protected IEnumerable<T> GetActiveVMsOfType<T>() where T : class
        {
            return _activeVMs.Where(vm => vm.Value.Instance is T).Select(vm => vm.Value.Instance as T);
        }
    }

My final VMFactory:

/// <summary>
   /// Provides view model controllers.
   /// </summary>
   public class VMControllerFactoryWithBroadcast : VMControllerFactory
    {
        public VMControllerFactoryWithBroadcast(IMemoryCache memoryCache) : base(memoryCache)
        {
        }

        /// <summary>
        /// Creates a view model controller and assigns it a key. 
        /// On subsequent calls, use the same key to return the same object.
        /// </summary>
        /// <param name="key">Identifies the object.</param>
        /// <returns>View model controller.</returns>
        public override VMController GetInstance(string key)
        {
            var cache = _controllersCache;

            if (!cache.TryGetValue(key, out Lazy<VMControllerWithNotificationBroadcast> cachedValue))
            {
                cachedValue = new Lazy<VMControllerWithNotificationBroadcast>(() => new VMControllerWithNotificationBroadcast(ResponseDelegate, key));
                cache.Set(key, cachedValue, GetCacheEntryOptions());
            }
            return cachedValue?.Value;
        }

        /// <summary>
        /// Broadcast the notification to the vmController identified by notification.ContextId.
        /// </summary>
        /// <typeparam name="T">Type of the notification to broadcast</typeparam>
        /// <param name="notification">The notification to broadcast</param>
        public void BroadcastNotification<T>(Notification.IVMNotification notification) where T : Notification.IVMNotification
        {
            var vmController = (VMControllerWithNotificationBroadcast)GetInstance(notification.ContextId);

            if (vmController == null)
                throw new Exception($"No vmController find for key '{notification.ContextId}'");

            vmController.BroadcastNotification<T>(notification);       
        }
   }

I had to make some changes in base class to override what I needed.

I've tried to be the less intrusive.

I hope I'm clear. and you understand my english.

yes, I managed to publish messages between the view model but the solution involves changes to the library code.

Have another solution ?

ETA on SignalR Alpha 2 Release?

I have an application in development for my workplace that makes significant use of dotnetify. I see commits in master related to upgrading to the latest version of SignalR. Is there a way to use this work other than syncing the head of master? What work remains? I can help...

Webform support?

With ASP.NET 4.5 being supported, would I be able to integrate this into a project containing webforms at all? I currently have a WebAPI2 project that currently uses signalR for very basic "hey go do a postback" notifications, and then I'm relying on annoying ajax postbacks and updatepanels to do work. I was looking at this as possible an easy way to get around that bottleneck without reinventing the wheel and moving to MVC

v2.2.0-pre nuget breaks ASP.NET-Core-Project with net462-TargetFramework

@dsuryd : first of all thanks for this wonderful framework, I've been searching a long time for such a solution and dotNetify is almost the perfect WebFramework IMHO.

I have encountered a minor issue with the latest nuget-package:
My webproject is a ASP.NET-Core-Project with <TargetFramework>net462</TargetFramework>.
The new dependency
Version v2.2.0-pre of 'DotNetify.SignalR'-Nuget causes compilation-errors in the Startup-Class:
image

I don't fully understand the reason for this new net462-dependency : in my opinion, the original 'DotNetify'-package should be the target for "old" ASP.NET MVC Dependencies, whereas the newer 'DotNetify.SignalR' & 'DotNetify.Core' should be used for ASP.NET Core projects only... or am I missing something here?

MemoryCache System.ArgumentNullException: Value cannot be null.

Ignore this... was a dumb error in my code.
(and Visual Studio Code was playing tricks on me and not catching the exception in my code)


I get the following Exception. I believe this is because I have some null properties that I'm trying to pass from server to the client...

It throws the Exception on a worker thread and I only get the following detail:

---- DEBUG ASSERTION FAILED ----
---- Assert Short Message ----
System.ArgumentNullException: Value cannot be null.
Parameter name: key
at Microsoft.Extensions.Caching.Memory.MemoryCache.TryGetValue(Object key, Object& result)
at Microsoft.Extensions.Caching.Memory.CacheExtensions.TryGetValue[TItem](IMemoryCache cache, Object key, TItem& value)
at DotNetify.VMControllerFactory.GetInstance(String key)
at DotNetify.DotNetifyHub.Response_VM(String connectionId, String vmId, String vmData)
at DotNetify.VMController.PushUpdates()
at DotNetify.VMController.OnUpdateVM(String connectionId, String vmId, Dictionary2 data) at DotNetify.DotNetifyHub.Update_VM(String vmId, Dictionary2 vmData)
---- Assert Long Message ----

Download / Upload files

Hello Dicky,
Further to our discussion in another thread :

As per your suggestion, to download a file, I am setting a VM property with the generated pdf file location. On the client side, listen to this property changed event, and then execute a window.open() to open the file on the browser.

Works fine, but in this approach there is a small security risk, as the full path of the location can be known - and hence it will be just a matter of time, when other users on the network will figure out my logic and starting "experimenting" with urls on their browsers to download files generated from other users.

For generated files, maybe I can delete these generated pdf files on the server periodically (these generated pdfs can be stored in a 'temporary' directory), but then what about files which are part of a "document management system" which are stored on specific directories on the server. One way, I can think of is that the method will copy the desired files from the "documents" directory to the temporary directory which will then be served to the client and then similar to the generated pdfs, keep on deleting these files periodically.

Is there no way that I can have something like the response object of mvc, where the file is being "pushed" to the client browser.

Appreciate your views on how to tackle this situation in dotnetify.

In Asp.net MVC, I used the response object to serve the files from such directories and the <hiddenSegments> in the web.config will make sure that the browser does not have direct access to that directory.

Return Http status codes and authentication, authorization

I am very interested for this framework and kudos to the creator.
Currently i am starting a new project and although i want to use dotNetify there are a lot of things keeping me back, things that i don't understand currently and there is not a proper documentation that covers every scenario.

What i would like to ask in this post is how we return http status codes? And how do we apply authentication and authorization on view models?

Also how we can take advantage of the DI in asp.net core, what is the role of the Http request pipeline now that almost all requests are through SignalR, can i use ActionFilters, or serve static content, how to add log and audit capabilities? Previously i could register a middleware and i was done, now with SignalR the picture is not clear for me.

Plus, is there somewhere a roadmap with what is currently under development, what are the next steps for the framework?

Again well done to the creator(s) of this framework, i really like it but i need to be more confident before i dive in.

Cookie Authentication

I am not sure if this is the right place to ask, but do you have an example of a simple Authentication option with the users stored in a database or a file? In the App-Template you used the google Authentication, but I would need a custom Authentication with Authorize control of specific html pages. Maybe you can point me in the right direction.

Dotnetify from Deskstop WPF App

Hi

I am wondering if there is any way to have dotNetify work from a WPF desktop app.
We are putting together a small web app using dotNetify and have been asked to make part of it as desktop app only not just web.

As I have started to create the web part using dotNetify-React, I would like to connect the WPF App to the backend using dotNetify as well.

Is this possible? Do you have any guidance?

Thanks for such a great platform.

PushUpdates/Changed inside a class

I have a problem with updating the view when a property is changed inside a class.

I got a class for translating a text:

public string TableName { get; set; }
public string Content { get; set; }
public string TranslatedText { get; set; }

public DictionaryText(string tableName, string content)
{
TableName = tableName;
Content = content;
TranslatedText = content;
MainWindowVM.OnLanguageChanged += LanguageChanged;
}
private void LanguageChanged(object source, LanguageEventArgs e)
{
string language = e.GetLanguage();
TranslatedText = CommonTableReader.GetMessage(Content, TableName, language);
}

I am using this class as a property in a ViewModel for my Page:

public class MainPageVM : PageVM
{
public DictionaryText PageName { get; set; }
public MainPageVM()
{
PageName = new DictionaryText("messages", "Descr_MainPage");
}
}

This is the HTML Code:

<h3 data-bind="text: PageName.TranslatedText"></h3>

The problem is that the TranslatedText is not updated when the event occurs. When I manually call Changed(()=>PageName) in the MainPageVM it is updated correctly. Is there a way to call Changed inside the DictionaryText class?

SignalR version used

Hi There.
Good work on this :)

The (very old - pre RC of even .net core) experimental version of SignalR used for this is no where near production ready though.

I used this version of SignalR live for 6 months on a production system, and would randomly receive alerts from users stating the site was down (Reporting Status code 502).
Upon further investigation it lead me to finally find that SignalR was causing it. Hub transport (Websockets / long polling - didn't matter which transport protocol was used) would just freeze due to the pluggable formatters failing.

See here: aspnet/SignalR#62

This is just a heads up that it'd be better to see if 2.2.1 (signalR) works when targeting .Net 4.6.1 under .Net Standard 2.0, or simply just wait for the Official SignalR release which is coming very soon :)

How to contribute

Love this project, thanks for open sourcing it. How can I contribute? Is there a roadmap somewhere? Are you planning on keeping a list features/bugs somewhere?

Hello World example "return window.vmStates.HelloWorldVM;" not working correctly.

I've been playing around with the Hello World code example, however I consistently get an error when the getInitialState() method of the HelloWorld.jsx class calls "return window.vmStates.HelloWorldVM;".

The error I get is (I renamed HelloWorldVM to FormTestVM, everything else is identical):

Uncaught TypeError: Cannot read property 'FormTestVM' of undefined
at Object.getInitialState (eval at (bundle.js:1075), :34:31)
at new eval (eval at (bundle.js:2155), :653:54)
at eval (eval at (bundle.js:1411), :297:18)
at measureLifeCyclePerf (eval at (bundle.js:1411), :77:12)
at ReactCompositeComponentWrapper._constructComponentWithoutOwner (eval at (bundle.js:1411), :296:16)
at ReactCompositeComponentWrapper._constructComponent (eval at (bundle.js:1411), :282:21)
at ReactCompositeComponentWrapper.mountComponent (eval at (bundle.js:1411), :190:21)
at Object.mountComponent (eval at (bundle.js:295), :46:35)
at ReactDOMComponent.mountChildren (eval at (bundle.js:1723), :238:44)
at ReactDOMComponent._createInitialChildren (eval at (bundle.js:1435), :699:32)

and it is always thrown at this line:

return window.vmStates.FormTestVM;

I changed this to:

return this.vm;

and it seems to work correctly. Is there something I have done incorrectly, or is this a bug?

Source if model?

I was going through the examples and I notice:

  public ActionResult Demo(string id, object iModel)
  {
     if (String.IsNullOrEmpty(id))
        id = "index";

     if (id.EndsWith("_cshtml"))
        return View("/Views/" + id.Replace("_cshtml", ".cshtml"), iModel != null && iModel.GetType() != typeof(object) ? iModel : null);
     return File(Server.MapPath("/Views/" + (id.EndsWith(".html") ? id : id + ".html")), "text/html");
  }

But I am not sure where the object iModel is generated?

Ideas?

Two Way Binding to Code Behind (Javascript)

Is there a way to create a two way Binding to a variable in the code behind?

I got a DropDown for example and I want to bind the selected value to a variable in javascript. Later I want to set this variable via javascript to a different value.
I used a variable with a _ at the beginning, but setting the value in javascript doesn't update the view.

Sorry it was my fault. Now it's working as expected.

Use dotnetify outside of react components?

All examples that I have seen, demonstrate using dotnetify directly inside react component's getIntialState() function, and it is required to pass the current instance of the component: dotnetify.react.connect(vmName, component)

Is it possible to use dotnetify outside of a react component, so that it may be used with any client-side framework or inside an external service for example? Can we get an instance of a vm and dispatch changes and subscribe to server changes outside of react? Or would it just make sense to use signalR directly in that case?

Components

In the app-template I noticed that you are using some components to reuse html code.
This was the thing I missed until now.

Do you have some documentation about this or maybe a link where I can read more about it?

Ok it seems that this are simple knockout components. I am not sure how to load a dotnetify BaseVM as a viewmodel of the component, so I don't need to pass every parameter on it's own. Is this even possible?

It would be great to be able to create views with associated viewmodels that I can reuse everywhere as I do in wpf.

Here is an example. I want to create a text that translates automatically.
Let's call it dictionary-text.
I got a ViewModel looks like this:

public class DictionaryText : BaseVM
{
	public string TableName { get; set; }
	public string Content { get; set; }
	public string TranslatedText { get; set; }

	public DictionaryText()
	{
		TableName = "";
		Content = "";
		TranslatedText = "";
		MainWindowVM.OnLanguageChanged -= LanguageChanged;
		MainWindowVM.OnLanguageChanged += LanguageChanged;
		LanguageChanged(null, new LanguageEventArgs(MainWindowVM._SelectedLanguage));
	}

	private void LanguageChanged(object source, LanguageEventArgs e)
	{
		TranslatedText = CommonTableReader.GetMessage(Content, TableName, e.GetSelectedLanguage());
		Changed(() => TranslatedText);
		PushUpdates();
	}

	public override void Dispose()
	{
		base.Dispose();
		MainWindowVM.OnLanguageChanged -= LanguageChanged;
	}
}

Now I want to create a component which can be used everywhere in HTML like this:

<dictionary-text data-vm="DictionaryTextVM" params="Content: 'Descr_ExampleID', TableName: 'messages'"/>

In the ViewModel the TableName Property should now be set to messages and the Content property should be Descr_ExampleID.

The Text the dictionary-text is going to display is the TranslatedText Property.

Is there any way I can achieve something like this?

problem when navigation property is introduced in model

Hi Dicky,

Great utility !
I am still in the learning curve.
My data model 'Company' contains the following navigation property
public virtual ICollection Locations { get; set; }

In the view model (which inherits from BaseVM), I have the following property
public IEnumerable Companys
{
get { return db.Companys.ToList();}
}

On execution, I don't get the data in the browser. I have stepped through the code and the data is being populated at the View Model.
As soon as I remove the navigation property from the Model, it works !
What might I be doing wrong?

Thanks

Deploy issues on Ubuntu 16.04.2 LTS (xenial)

Using: Ubuntu 16.04.2 LTS (GNU/Linux 4.4.0-77-generic x86_64)
dotNetity: wget of master.zip as of today.

After succesfully testing dotNetify on a Linux vagrant VM (Ubuntu 16.04.02), I am trying to start the WebApplication.Core.React example on an existing Ubuntu server on our LAN.

First problem I ran into, is that only the 2.0.0 dotnet core framework was present on that machine.

tw@srv-nondisclosed-02:~/PublishOutput$ dotnet exec WebApplication.Core.React.dll
It was not possible to find any compatible framework version
The specified framework 'Microsoft.NETCore.App', version '1.0.4' was not found.
  - Check application dependencies and target a framework version installed at:
      /
  - Alternatively, install the framework version '1.0.4'.

I solved it for now by apt install dotnet-dev-1.0.4 (after failed attempts to reconfigure the packages to 2.0.0, I got stuck on a Could not load file or assembly 'System.Threading, Version=4.1.0.0', so decided to use 1.0.4 for the time being).

To your example I added one line to the WebHostBuilder: .UseUrls("http://0.0.0.0:5000") , so I can browse to it from windows. That gave a 500.

Then I added app.UseDeveloperExceptionPage(); to the config. This shows (from a browser) the following exception is causing the fail:

System.InvalidOperationException: Cannot return null from an action method with a return type of 'Microsoft.AspNetCore.Mvc.IActionResult'.
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__27.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextActionFilterAsync>d__25.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeNextResourceFilter>d__22.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeAsync>d__20.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.RouterMiddleware.<Invoke>d__4.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Builder.Extensions.MapMiddleware.<Invoke>d__3.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.<Invoke>d__6.MoveNext()

Since the machine should be the same as my vagrant VM, this surprises me.

apt list --installed | grep dotnet shows on both machines:

dotnet-dev-1.0.4/xenial,now 1.0.4-1 amd64 [installed]
dotnet-host/xenial,now 2.0.0-preview2-25407-01-1 amd64 [installed,automatic]
dotnet-hostfxr-1.0.1/xenial,now 1.0.1-1 amd64 [installed,automatic]
dotnet-hostfxr-1.1.0/xenial,now 1.1.0-1 amd64 [installed,automatic]
dotnet-hostfxr-2.0.0/xenial,now 2.0.0-1 amd64 [installed,automatic]
dotnet-runtime-2.0.0/xenial,now 2.0.0-1 amd64 [installed,automatic]
dotnet-sdk-2.0.0/xenial,now 2.0.0-1 amd64 [installed]
dotnet-sharedframework-microsoft.netcore.app-1.0.5/xenial,now 1.0.5-1 amd64 [installed,automatic]
dotnet-sharedframework-microsoft.netcore.app-1.1.2/xenial,now 1.1.2-1 amd64 [installed,automatic]

Any clue?

Xamarin Integration?

Are there any plans to have DotNetify support Xamarin? It seems like this would be a great fit, re-using Xamarin View Models in my Web Application. I've attempted installing this in a Portable Class Library (4.5, Profile=7) but received error:

"Could not install package 'Microsoft.Owin.Host.SystemWeb 2.1.0'. You are trying to install this package into a project that targets '.NETPortable,Version=v4.5,Profile=Profile7', but the package does not contain any assembly references or content files that are compatible with that framework. For more information, contact the package author."

Update List values on the browser.

Hi Dicky,

In my module with master and child records, I am in the process of doing CRUD with the child records. I will not save it to database as of now. I am only gathering and validating records of child table and will save to the database only after the master fields are also validated.

I have a potran_list with the child records related to the master and use the foreach to build a table in the browser.

<tbody id="tbodytablepotranlist" style="height:200px" data-bind="foreach: { data: potran_list, as: 'record' }, vmItemKey: 'sr'">

Each row also has a button, that will open up a modal with the values of that row for the user to edit. (These values are stored in separate observable properties and is not related to the list)

If the user chooses to save the changes, then he clicks the save button on the modal which is bound to a method (potranbtnok) which updates the specific list's record with the property values from the modal.

        public bool potranbtnok
        {
            get { return false; }
            set
            {
                potran_oktosave = true;

                //validate the properties - todo
                if (potran_oktosave)
                {
                    //Update potran_list
                    var recset = potran_list.FirstOrDefault(x => x.sr == potran_sr);
                    recset.name = potran_name;  //Store the value from the modal into recset which will also update potran_list.
                    //Do the same for other properties

                    Potranlineitemmodalclose = "close the modal";  //This will activate the vm.$on script which closes the modal
                }
            }
        }

When the potran_list is updated, I want to show the user the updated values in the table. How to "push" the list changes of that specific record to the browser.?

Also, I tried removing and adding it like this
`
this.RemoveList(() => potran_list, potran_sr);`
this.AddList(() => potran_list, recset);`

and this removes the record from the browser but does not add it back.

But I can always add a new record with a new sr,

this.AddList(() => potran_list, new potran_listViewModel {sr=3,, code = potran_code, name=potran_name, confirmdocno = potran_confirmdocno, qty = potran_qty, price = potran_price, total = potran_total });

I looked into your Simple list example - but don't know how to apply to the above situation.
Need your help. Thanks.

Absence of Unit Tests

Example apps are obviously great. But Unit Tests will help to structure your code for extensibility and maintainability, in addition to quality check.

As I wanted to introduce DI into your library I saw a lot of statics, which is hard to DI. If unit tests were present, I believe this would've be better.

Trouble Pushing Data Back to Server

I have a component that gets its initial state from a parent component. I'm having a hard time getting this passed back to the server. Eventually the component will get a domain event and need to update the data from the server but I need the server side to have the initial state that was given to it in order to do the update correctly.

Here is my getInitialState method.

getInitialState() {
  this.vm = dotnetify.react.connect("RunFeedRow", this, );

        // Functions to dispatch state to the back-end.
        this.dispatch = state => this.vm.$dispatch(state);
        this.dispatchState = state => {
            this.setState(state);      // Optimistic update.
            this.vm.$dispatch(state);
        }

        this.setState({ Run: this.props.Run });
        this.vm.$dispatch({ SetState: this.props.Run });
        //var state = window.vmStates.RunFeedRow || {};

        return this.props.Run;
    }

I've tried to use this.setState and this.vm.$dispatch as listed on your documentation but the property never gets set on the backend (below):

public RunSummary Run { get; set; }
public Action<RunSummary> SetState => run =>
        {
            Run = run;
            Changed(nameof(Run));
        };

Any suggestions on what I could be doing wrong?

Session State

I would like to pass into the MasterVM some values from session state. How would I get access to the HttpContext?

Cannot run app after upgrade to VS2017 15.3.3

After upgrading VS2017 to the latest build I get the following when trying to run npm start:

0 info it worked if it ends with ok
1 verbose cli [ 'C:\\Program Files\\nodejs\\node.exe',
1 verbose cli   'C:\\Users\\jarrod.johnson\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js',
1 verbose cli   'start' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'prestart', 'start', 'poststart' ]
5 info lifecycle [email protected]~prestart: [email protected]
6 info lifecycle [email protected]~start: [email protected]
7 verbose lifecycle [email protected]~start: unsafe-perm in lifecycle true
8 verbose lifecycle [email protected]~start: PATH: C:\Users\jarrod.johnson\AppData\Roaming\npm\node_modules\npm\bin\node-gyp-bin;C:\github\jarrodj83\myapp.Portal\myapp.portal.dotnetify\node_modules\.bin;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Tools\MSVC\14.11.25503\bin\HostX86\x86;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\VC\VCPackages;C:\Program Files (x86)\Microsoft SDKs\TypeScript\2.3;C:\Program Files (x86)\Microsoft SDKs\TypeScript\2.3;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TestWindow;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\MSBuild\15.0\bin\Roslyn;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Team Tools\Performance Tools;C:\Program Files (x86)\Microsoft Visual Studio\Shared\Common\VSPerfCollectionTools\;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.6.1 Tools\;C:\Program Files (x86)\Windows Kits\10\bin\x86;C:\Program Files (x86)\Windows Kits\10\bin\10.0.15063.0\x86;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\\MSBuild\15.0\bin;C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\IDE\;C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\Common7\Tools\;C:\PROGRAM FILES (X86)\MICROSOFT VISUAL STUDIO\2017\ENTERPRISE\COMMON7\IDE\EXTENSIONS\DEMRJBIE.MOU\lib\win32\x86;C:\Program Files\Docker\Docker\Resources\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Shoreline Communications\ShoreWare Client\;C:\Program Files (x86)\Shoreline Communications\ShoreWare Client\win64;C:\Program Files (x86)\PuTTY\;C:\Program Files (x86)\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files\Microsoft SQL Server\130\DTS\Binn\;C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;C:\Program Files (x86)\Microsoft SDKs\TypeScript\1.0\;C:\Program Files\Microsoft SQL Server\120\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\Client SDK\ODBC\130\Tools\Binn\;C:\Program Files (x86)\Microsoft SQL Server\130\Tools\Binn\ManagementStudio\;C:\Program Files\TortoiseSVN\bin;C:\ProgramData\chocolatey\bin;C:\Program Files (x86)\Sennheiser\SoftphoneSDK\;C:\Program Files\Seq\;C:\Program Files\dotnet\;C:\Program Files\Git\cmd;C:\Program Files\PuTTY\;C:\Program Files\nodejs\;C:\Ruby24-x64\bin;C:\Users\jarrod.johnson\AppData\Local\Microsoft\WindowsApps;C:\Program Files (x86)\Microsoft VS Code\bin;C:\Users\jarrod.johnson\AppData\Local\atom\bin;C:\Program Files (x86)\Xming;C:\Program Files (x86)\Xming;C:\Users\jarrod.johnson\AppData\Roaming\npm;C:\Users\jarrod.johnson\AppData\Local\Programs\Fiddler;C:\Users\jarrod.johnson\.nuget\packages\newtonsoft.json\10.0.1\tools;C:\Users\jarrod.johnson\.nuget\packages\microsoft.codeanalysis.analyzers\1.1.0\tools;C:\Program Files\dotnet\sdk\NuGetFallbackFolder\microsoft.entityframeworkcore.tools\2.0.0\tools;C:\Users\jarrod.johnson\.nuget\packages\newtonsoft.json\10.0.2\tools;C:\Users\jarrod.johnson\.nuget\packages\newtonsoft.json\10.0.3\tools;C:\Users\jarrod.johnson\.nuget\packages\autofixture\3.50.6\tools
9 verbose lifecycle [email protected]~start: CWD: C:\github\jarrodj83\myapp.Portal\myapp.portal.dotnetify
10 silly lifecycle [email protected]~start: Args: [ '/d /s /c',
10 silly lifecycle   'concurrently "react-scripts start" "dotnet watch run" --kill-others' ]
11 silly lifecycle [email protected]~start: Returned: code: 1  signal: null
12 info lifecycle [email protected]~start: Failed to exec start script
13 verbose stack Error: [email protected] start: `concurrently "react-scripts start" "dotnet watch run" --kill-others`
13 verbose stack Exit status 1
13 verbose stack     at EventEmitter.<anonymous> (C:\Users\jarrod.johnson\AppData\Roaming\npm\node_modules\npm\lib\utils\lifecycle.js:289:16)
13 verbose stack     at emitTwo (events.js:106:13)
13 verbose stack     at EventEmitter.emit (events.js:191:7)
13 verbose stack     at ChildProcess.<anonymous> (C:\Users\jarrod.johnson\AppData\Roaming\npm\node_modules\npm\lib\utils\spawn.js:40:14)
13 verbose stack     at emitTwo (events.js:106:13)
13 verbose stack     at ChildProcess.emit (events.js:191:7)
13 verbose stack     at maybeClose (internal/child_process.js:891:16)
13 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:226:5)
14 verbose pkgid [email protected]
15 verbose cwd C:\github\jarrodj83\myapp.Portal\myapp.portal.dotnetify
16 verbose Windows_NT 10.0.14393
17 verbose argv "C:\\Program Files\\nodejs\\node.exe" "C:\\Users\\jarrod.johnson\\AppData\\Roaming\\npm\\node_modules\\npm\\bin\\npm-cli.js" "start"
18 verbose node v6.11.1
19 verbose npm  v5.3.0
20 error code ELIFECYCLE
21 error errno 1
22 error [email protected] start: `concurrently "react-scripts start" "dotnet watch run" --kill-others`
22 error Exit status 1
23 error Failed at the [email protected] start script.
23 error This is probably not a problem with npm. There is likely additional logging output above.
24 verbose exit [ 1, true ]

Does anything stand out here to you that might be causing this issue?

Routing

Hello,

I have little bit struggling with the routing. I have one page (Index) with the list of items and I want to route to their details. For first request it is for good, but the problem is when I select another item, routing is not working. I follow yours tutorial so ApplicationDetail view model has registred OnRouted event. But from network snapshot is obvious that the second request for detail is not received.

Here are my project structure and components.

image

Here is the network communication

image

Here are compontenst:

import React from 'react';
import dotnetify from 'dotnetify';
import ReactDOM from 'react-dom';
import { RouteLink, RouteTarget } from 'dotnetify/dist/dotnetify-react.router'

class Index extends React.Component {
    constructor(props) {
        super(props);
        this.vm = dotnetify.react.connect("Index", this);
        this.vm.onRouteEnter = (path, template) => {
            template.Target = "ApplicationMonitor";
            //// Must dismount existing component on RouteTarget before mounting a new one.
            //if (this.applicationMonitor && this.hasApplicationLoaded) {
            //    ReactDOM.unmountComponentAtNode(this.applicationMonitor.getDOMNode());
            //    this.setState({ open: false });
            //}
            //this.hasApplicationLoaded = true;
        }
        this.state = { Applications: undefined };
    }

    componentWillUnmount() {
        //ReactDOM.unmountComponentAtNode(this.applicationMonitor.getDOMNode());
        this.vm.$destroy();
    }

    render() {
        if (this.state.Applications == null)
            return <div></div>
        const apps = this.state.Applications.map(app =>
            <RouteLink vm={this.vm} route={app.Route} key={app.Info.Id}>
                <div key={"div" + app.Info.Id} className="book col-md-3">
                    <strong>{app.Info.Name}</strong>
                </div>
            </RouteLink>
        )
        return (
            <div className="row">
                {apps}
                <div id="ApplicationMonitor" />
                
            </div>
        );
    }
}
export class Home extends React.Component {
    render() {
        return (
               <div>Home</div>
        );
    }
}
export default Index;
import React from 'react';
import dotnetify from 'dotnetify';

class ApplicationDetail extends React.Component {
    constructor(props) {
        super(props);
        this.vm = dotnetify.react.connect("ApplicationDetail", this);
        this.state = { CurrentApplication: { Id : 0, Name: ""} };      
    }
    componentWillUnmount() {
        this.vm.$destroy();
    }
    render() {
        var app = this.state.CurrentApplication;
        return (
            <div className="row">
                {app.Name}
            </div>
        )
    }
}

export default ApplicationDetail;

ViewModels

    public class Index : BaseVM, IRoutable
    {
        private readonly IApplicationListFacade _appListFacade;

        public RoutingState RoutingState { get; set; }

        public IEnumerable<object> Applications { get; set; }

        public Index(IApplicationListFacade applicationListFacade)
        {
            _appListFacade = applicationListFacade;

            this.RegisterRoutes(Constants.ROUTE_ROOOT, new List<RouteTemplate>
            {
                new RouteTemplate(Constants.DEFAULT_ROUTE) { UrlPattern = string.Empty },
                new RouteTemplate(Constants.APPLICATION_DETAIL_ROUTE) { UrlPattern = Constants.APPLICATION_ID_ROUTE_PATTERN, VMType = typeof(ApplicationDetail) },
            });

            Applications = _appListFacade.GetApplications()
                                          .Select(app =>
                                            new
                                            {
                                                Info = app,
                                                Route = this.GetRoute(Constants.APPLICATION_DETAIL_ROUTE, $"{Constants.APPLICATION_ROUTE_PATTERN}{app.Id}")
                                            }
                                          );

            Changed(nameof(Applications));
            PushUpdates();
        }
    }

    public class ApplicationDetail : BaseVM, IRoutable
    {
        private readonly IApplicationListFacade _appListFacade;

        public RoutingState RoutingState { get; set; }

        public Application CurrentApplication { get; set; }

        public ApplicationDetail(IApplicationListFacade applicationListFacade)
        {
            _appListFacade = applicationListFacade;

            this.OnRouted((sender, e) =>
            {
                if (!string.IsNullOrEmpty(e.From))
                {
                    var applicationId = e.From.Replace(Constants.APPLICATION_ROUTE_PATTERN, string.Empty);
                    if (int.TryParse(applicationId, out var id))
                    {
                        CurrentApplication = _appListFacade.GetApplicationById(id);
                        Changed(nameof(CurrentApplication));
                    }
                }
            });
        }
    }
    public static class Constants
    {
        public const string ROUTE_ROOOT = "Index";
        public const string DEFAULT_ROUTE = "Home";
        public const string APPLICATION_DETAIL_ROUTE = "ApplicationDetail";
        public const string APPLICATION_ROUTE_PATTERN = "ApplicationDetail/";
        public const string APPLICATION_ID_ROUTE_PATTERN = "ApplicationDetail(/:Id)";
    }

I do not know whats wrong. Can you help me please?

WebApplication.Core.React - Build errors

EmbeddedResource Include for:

ControlTypes.min.js
GridView.min.js
HelloWorld.min.js
index.min.js
LiveChart.min.js
SimpleList.min.js

files missing from repository.

Easy enough to resolve. Just pointing it out.

Disable debug in dotnetify.react

First of all, great work!

I was wondering if there is a way to set debug: false when using the dotnetify.react.connect code? I didn't see any way to do this other than modifying the source.

Thanks!

jQuery was not found error every time I try to use Visual Studio + Webpack

When I try to follow the "Hello World" example from Visual Studio/Webpack I get a jQuery was not found error.

image

I followed the steps exactly using both VS 2017 and VS Code, and got the same error both times.

I noticed when running Webpack that the list of bundled files didn't contain the jquery.js file that you showed in the image of your example.
image
image

Do you have any idea if I've made a mistake, or if there is another step I need to do? I've tried to follow the steps you posted multiple times on 2 machines and got the same issue on both.

Thanks,
Sonny

Binding action (eg: button click)

It would be desirable to be able to bind button actions (click) to ICommand (System.Windows.Input)... is a well establish pattern in .NET circles.

In any case... really well written framework, brings View Models written in C# right into HTML

Authentication with dotNetify

Hi
I am evaluating dotNetify for a new project and think the solution is excellent.
Before we adopt this solution I just have one question regarding authentication, we require a capability to restrict a part of our dashboard to logged in users but cannot see an example of how you achieve that with dotNetify.

Do you have an example project with authentication or a tutorial tucked away somewhere?

Thanks in advance.

Vue Support

Hi @dsuryd ,
Any chance you would support Vue.js ? the lib seems to be dependent on jQuery. any chance that dependency be optional?

Support for new ASP.Net Core 2.0 React.js and Redux VS template

With the new .Net Core SDK VS2017 has a new project template for a ASP.Net Core 2.0 project that builds a React.Js and Redux web application.

I've tried a quick hack with plugging dotNetify into it, but the approach of the standard VS templates (folders, routes, etc.) is a lot different than the approach taken with the dotNetfy samples.

Any hope of an update to the HelloWorld samples that starts with the new ASP.Net Core 2.0 templates?

SPA needs ~4s to load on mobile devices

Is there a reason, why mobile devices are really slow in loading the website?

I have got a SPA that has several nested pages. When it is initally loaded, or when I press reload, it needs 4s to render the content on mobile devices. But once it is loaded, I can switch in under <1s between the nested pages.

On a desktop pc the page is always loaded in <1s.

Compability with ASP.NET?

Would this solution be possible with ASP.NET as well? We're using a CMS that hasn't upgraded to .NET Core yet and won't do that in the foreseeable future. We're looking at implementing something similar to this there so that we can use React properly.

What things in .NET Core enabled you to use these things and if you were to implement this for ASP.NET are there any general tips on how to get this working?

Building in Visual Studio for Mac.

Hi,

I am trying to build and run in Visual Studio for Mac, and I am able to build and run Webapplication.Core, however a blank screen responds on the browser.

Any clues?

Thanks.

View and VM are loaded multiple times when using redirect

I first thought that I missed something, but the problem is also noticable on your webstore example.
When you click the link inside the carousel to books category, it is loaded two times. You can easily notice it by monitoring the network traffic with chrome.

In my case I have a MainPage that loads multiple subbpages. The Routes to these subpages are registered in the MainPageVM. The subpages then contains buttons to navigate to each other which are created using Redirect. But with each subpage that uses Redirect, the page will load as many times as Redirect to this page has been called.

Load only necessary JS files for each demo

I have been playing around with dotNetify and honestly I am impressed. The architecture is simple, the two-way data binding works great and having most of the business logic on the server side is just what many .NET developers would want. Forgot to mention that the examples are very easy to follow. You must have put a lot of hard work on this project. Thanks.

A small detail I noticed is that all the JS files are being loaded for each demo, that is because the demoApp.js file is bringing all these files regardless whether they are needed or not. Having a demoApp.js specific file for each example would solve this.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.