Giter VIP home page Giter VIP logo

codelab-android-dagger's People

Contributors

josealcerreca avatar manuelvicnt avatar osuleymanova avatar tiembo 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

codelab-android-dagger's Issues

Review sentence structure

In step 10, below the block Important- Best Practices, the sentence

"RegistrationViewModel it's already annotated with @Inject, RegistrationActivity needed it before."

might need to be reviewed for grammatical errors.
I'm not an expert but the sentence can be:

RegistrationViewModel is already annotated with @Inject, since RegistrationActivity needed it before.

Step 10 - RegistrationActivity or MainActivity?

By almost the end of step 10 we have the text:
"Instead, for the RegistrationActivity to create instances of RegistrationComponent, we need to expose its Factory out in the AppComponent interface."

But I guess instead "RegistrationActivity" you mean "MainActivity".

Nice job btw.

Typo in 11. Scoping Subcomponents

original:
that'll make that typehave a unique instance in the Component.

should be:
that'll make that type have a unique instance in the Component.

In section, Subcomponents, Tutorial doesn't show, explicitly, removal of registration component injectors from AppComponent

This paragraph is stated (truthfully): In AppComponent, we have to remove the methods that can inject registration view classes because these won't be used anymore, those classes will use the RegistrationComponent.

But, it'd be helpful to the student to be told explicitly to remove these lines from AppComponent:

    fun inject(activity: RegistrationActivity)
    fun inject(fragment: EnterDetailsFragment)
    fun inject(fragment: TermsAndConditionsFragment)

Furthermore, it'd probably be helpful to add a gotcha warning in the next section of the tutorial ("Scoping Subcomponents"), warning them that if they failed to remove those injector calls from AppComponent they will get this error:

/Users/dg891e/repos/googlecodelabs/android-dagger/app/build/tmp/kapt3/stubs/debug/com/example/android/dagger/di/AppComponent.java:8: error: [Dagger/IncompatiblyScopedBindings] com.example.android.dagger.di.AppComponent scoped with @Singleton may not reference bindings with different scopes:
public abstract interface AppComponent {
                ^
      @com.example.android.dagger.di.ActivityScope class com.example.android.dagger.registration.RegistrationViewModel

Add separate branch implementing optional step from codelab

Add separate branch implementing optional step from codelab:

  1. [Optional] Try Dependency Injection on your own
    There's one more part of the codelab app for you to experiment with, and that's refactoring to have a SplashScreen: MainActivity.kt handles the logic of what screen needs to be shown when opening the app. That's problematic because we're doing conditional dependency injection, only injecting when the user will remain on the MainActivity.

These steps don't contain comments or code, so try it on your own:

Create a SplashActivity with a SplashViewModel that handles the logic of what screen to display.
As we've been doing, use dependency injection in SplashActivity to get fields injected by Dagger.
Remove the logic in the onCreate method of the MainActivity.kt since when the Activity is opened, the user will be logged in.

Typo in https://developer.android.com/codelabs/android-dagger#6

At the end of text:
Your project should now build with no errors.. Dagger has generated the application graph successfully and you're ready to use it.

It should be:
Your project should now build with no errors. Dagger has generated the application graph successfully and you're ready to use it.

Tipo on https://developer.android.com/codelabs/android-dagger#7

On this step here there is the following note:
Note: If you get an error saying that DaggerAppComponent doesn't exist in the project. It's because you have to build the project so the Dagger annotation processor can generate the code.

It should be:
Note: If you get an error saying that DaggerAppComponent doesn't exist in the project., it's because you have to build the project so the Dagger annotation processor can generate the code.

Problem at tab Multiple Activities With Same Scope

First of all, I would like to thank you for the great codelab, beautiful explanation. Even as an experienced user of dagger I learned a lot from it 👏👌

There is this extra line, which I think should not be there at the bottom of the tab Multiple Activities With Same Scope

as we are in the MainActivity, setContentView() is setting a view of activity_settings

I am attaching a screenshot for reference.

image

Thank you!

Application test crashes for security error

If you get this error:
Caused by: androidx.test.espresso.InjectEventSecurityException: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission

Then,
In the ApplicationTest file:
Replace:
onView(withId(R.id.password)).perform(typeText("password"), closeSoftKeyboard())
with:
onView(withId(R.id.password)).perform(replaceText("password"), closeSoftKeyboard())

(two places in the file)

Content of MainActivity.kt in the code block is wrong

class MainActivity : AppCompatActivity() {

// 1) Remove userManager field
@Inject
lateinit var userManager: UserManager

@Inject
lateinit var mainViewModel: MainViewModel

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_settings) <<<<<<<<<<<<< Not Supposed to be here <<<<<<<<<<

    // 2) Grab userManager from appComponent to check if the user is logged in or not
    val userManager = (application as MyApplication).appComponent.userManager()
    if (!userManager.isUserLoggedIn()) { ... }
    else {
        setContentView(R.layout.activity_main)
        // 3) If the MainActivity needs to be displayed, we get the UserComponent
        // from the application graph and gets this Activity injected
        userManager.userComponent!!.inject(this)
        setupViews()
    }
}
...

}

injection on a private member

in step 7 there is an injection annotation on a private member
`class MainActivity : AppCompatActivity() {

// @Inject annotated fields will be provided by Dagger
@Inject
private lateinit var userManager: UserManager

@Inject
private lateinit var mainViewModel: MainViewModel

...

} class MainViewModel @Inject constructor(private val userDataRepository: UserDataRepository) { ... } class UserDataRepository @Inject constructor(private val userManager: UserManager) { ... }`
Isn't it supposed for the annotation not to be on a private member

Move inject before onAttach for Fragment

Important - Best practices

An Activity injects Dagger in the onCreate method before calling super.
A Fragment injects Dagger in the onAttach method after calling super.

https://codelabs.developers.google.com/codelabs/android-dagger/#9

Constructor injection is preferred whenever possible because javac will ensure that no field is referenced before it has been set, which helps avoid NullPointerExceptions. When members injection is required (as discussed above), prefer to inject as early as possible. For this reason, DaggerActivity calls AndroidInjection.inject() immediately in onCreate(), before calling super.onCreate(), and DaggerFragment does the same in onAttach(), which also prevents inconsistencies if the Fragment is reattached.

https://dagger.dev/dev-guide/android.html

The content of the codelab and the content of the Dagger's document conflict.

There are several related PRs:

https://github.com/google/dagger/pull/603/files
https://github.com/google/dagger/pull/605/files

The order of super.onAttach () calls in the Dagger documentation has changed and I think this is the best practice.

Dagger injection on Fragments

Hi Manuel, how are you?

On the Android developers documentation it says:
https://developer.android.com/training/dependency-injection/dagger-android#injecting-activities
"When using fragments, inject Dagger in the fragment's onAttach() method. In this case, it can be done before or after calling super.onAttach()."

On the codelab about dagger it says:
https://developer.android.com/codelabs/android-dagger#9
"A Fragment injects Dagger in the onAttach method after calling super."

Which one is correct?
Would you please let me know, and correct where it is wrong, please?

Thanks a lot for the great material that you built up about Dagger.

Best regards,

Rodrigo

FakeStorage unresolved reference on TestStorageModule

TestStorageModule from androidTest shows an unresolved reference error for FakeStorage on the solution branch, even though the instrumented tests run successfully.
FakeStorage is located at the sharedTest package, and this package is shared with tests through sourceSets, but it looks like sharing code this way is not supported anymore, according to this comment on Google Issue Tracker.

sourceSets {
        String sharedTestDir = 'src/sharedTest/java'
        test {
            java.srcDir sharedTestDir
        }
        androidTest {
            java.srcDir sharedTestDir
        }

    }

A suggestion found on the same comment on Google Issue Tracker is to create a new module with the code that needs to be shared and add it as a dependency for testImplementation and androidTestImplementation.

testImplementation project(path: ':shared-test')
androidTestImplementation project(path: ':shared-test') 

Android Studio version:

Android Studio Giraffe | 2022.3.1 Patch 2
Build #AI-223.8836.35.2231.10811636, built on September 14, 2023

Mockito cannot mock final classes error

To fix the below error which occurs when running unit tests that have a dependency with the UserManager class, we need to update Mockito to a version higher than 5.0.0 because mocking final classes feature is enabled by default. In my case updating Mockito to version 5.3.1 fixed the issue.

Solution:
testImplementation 'org.mockito:mockito-core:5.3.1'

Problem:

Mockito cannot mock this class: class com.example.android.dagger.user.UserManager.
Can not mock final classes with the following settings :
 - explicit serialization (e.g. withSettings().serializable())
 - extra interfaces (e.g. withSettings().extraInterfaces(...))

You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class java.lang.Object, class com.example.android.dagger.user.UserManager]
org.mockito.exceptions.base.MockitoException: 
Mockito cannot mock this class: class com.example.android.dagger.user.UserManager.
Can not mock final classes with the following settings :
 - explicit serialization (e.g. withSettings().serializable())
 - extra interfaces (e.g. withSettings().extraInterfaces(...))

You are seeing this disclaimer because Mockito is configured to create inlined mocks.
You can learn about inline mocks and their limitations under item #39 of the Mockito class javadoc.

Underlying exception : org.mockito.exceptions.base.MockitoException: Could not modify all classes [class java.lang.Object, class com.example.android.dagger.user.UserManager]
	at app//com.example.android.dagger.registration.RegistrationViewModelTest.setup(RegistrationViewModelTest.kt:32)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/java.lang.reflect.Method.invoke(Unknown Source)
	at app//org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
	at app//org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
	at app//org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
	at app//org.junit.internal.runners.statements.RunBefores.invokeMethod(RunBefores.java:33)
	at app//org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:24)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
	at app//org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
	at app//org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
	at app//org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
	at app//org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
	at app//org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
	at app//org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
	at app//org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
	at app//org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
	at app//org.junit.runners.ParentRunner.run(ParentRunner.java:413)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.runTestClass(JUnitTestClassExecutor.java:110)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:58)
	at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecutor.execute(JUnitTestClassExecutor.java:38)
	at org.gradle.api.internal.tasks.testing.junit.AbstractJUnitTestClassProcessor.processTestClass(AbstractJUnitTestClassProcessor.java:62)
	at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at [email protected]/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at [email protected]/java.lang.reflect.Method.invoke(Unknown Source)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:36)
	at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
	at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:33)
	at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:94)
	at jdk.proxy1/jdk.proxy1.$Proxy2.processTestClass(Unknown Source)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker$2.run(TestWorker.java:176)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.executeAndMaintainThreadName(TestWorker.java:129)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:100)
	at org.gradle.api.internal.tasks.testing.worker.TestWorker.execute(TestWorker.java:60)
	at org.gradle.process.internal.worker.child.ActionExecutionWorker.execute(ActionExecutionWorker.java:56)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:133)
	at org.gradle.process.internal.worker.child.SystemApplicationClassLoaderWorker.call(SystemApplicationClassLoaderWorker.java:71)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.run(GradleWorkerMain.java:69)
	at app//worker.org.gradle.process.internal.worker.GradleWorkerMain.main(GradleWorkerMain.java:74)
Caused by: org.mockito.exceptions.base.MockitoException: Could not modify all classes [class java.lang.Object, class com.example.android.dagger.user.UserManager]
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:152)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:365)
	at app//net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:174)
	at app//net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:376)
	... 45 more
Caused by: java.lang.IllegalStateException: 
Byte Buddy could not instrument all classes within the mock's type hierarchy

This problem should never occur for javac-compiled classes. This problem has been observed for classes that are:
 - Compiled by older versions of scalac
 - Classes that are part of the Android distribution
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:237)
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.mockClass(InlineBytecodeGenerator.java:198)
	at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:46)
	at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator$1.call(TypeCachingBytecodeGenerator.java:43)
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:152)
	at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:365)
	at net.bytebuddy.TypeCache.findOrInsert(TypeCache.java:174)
	at net.bytebuddy.TypeCache$WithInlineExpunction.findOrInsert(TypeCache.java:376)
	at org.mockito.internal.creation.bytebuddy.TypeCachingBytecodeGenerator.mockClass(TypeCachingBytecodeGenerator.java:36)
	at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMockType(InlineByteBuddyMockMaker.java:252)
	at org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker.createMock(InlineByteBuddyMockMaker.java:231)
	at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:35)
	at org.mockito.internal.MockitoCore.mock(MockitoCore.java:69)
	at org.mockito.Mockito.mock(Mockito.java:1933)
	at org.mockito.Mockito.mock(Mockito.java:1844)
	... 45 more
Caused by: java.lang.IllegalArgumentException: Unsupported class file major version 61
	at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:196)
	at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:177)
	at net.bytebuddy.jar.asm.ClassReader.<init>(ClassReader.java:163)
	at net.bytebuddy.utility.OpenedClassReader.of(OpenedClassReader.java:86)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default$ForInlining.create(TypeWriter.java:3824)
	at net.bytebuddy.dynamic.scaffold.TypeWriter$Default.make(TypeWriter.java:2166)
	at net.bytebuddy.dynamic.scaffold.inline.RedefinitionDynamicTypeBuilder.make(RedefinitionDynamicTypeBuilder.java:224)
	at net.bytebuddy.dynamic.scaffold.inline.AbstractInliningDynamicTypeBuilder.make(AbstractInliningDynamicTypeBuilder.java:123)
	at net.bytebuddy.dynamic.DynamicType$Builder$AbstractBase.make(DynamicType.java:3595)
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.transform(InlineBytecodeGenerator.java:344)
	at java.instrument/java.lang.instrument.ClassFileTransformer.transform(Unknown Source)
	at java.instrument/sun.instrument.TransformerManager.transform(Unknown Source)
	at java.instrument/sun.instrument.InstrumentationImpl.transform(Unknown Source)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses0(Native Method)
	at java.instrument/sun.instrument.InstrumentationImpl.retransformClasses(Unknown Source)
	at org.mockito.internal.creation.bytebuddy.InlineBytecodeGenerator.triggerRetransformation(InlineBytecodeGenerator.java:233)
	... 59 more


Step 8 android.os.UserManager cannot be provided without an @Inject constructor

Step 8 -> Using Dagger in the Main Flow -> 2.
Error when building:
e: /Users/lazarristic/PersonalWorkspace/Android/Learning/Dagger/android-dagger/app/build/tmp/kapt3/stubs/debug/com/example/android/dagger/di/AppComponent.java:7: error: [Dagger/MissingBinding] android.os.UserManager cannot be provided without an @Inject constructor or an @Provides-annotated method. public abstract interface AppComponent { ^ android.os.UserManager is injected at com.example.android.dagger.main.MainActivity.userManager com.example.android.dagger.main.MainActivity is injected at com.example.android.dagger.di.AppComponent.inject(com.example.android.dagger.main.MainActivity)

Android Studio has imported android.os.UserManager instead of com.example.android.dagger.user.UserManager

Please add imports in code.

Strange sample code?

The following code from the codelab puzzled me because the private function userJustLoggedIn() was not called from anywhere.

@Singleton
class UserManager @Inject constructor(...) {
    //Remove line
    var userDataRepository: UserDataRepository? = null

    var userComponent: UserComponent? = null
          private set

    fun isUserLoggedIn() = userComponent != null

    fun logout() {
        userComponent = null
    }

    private fun userJustLoggedIn() {
        userComponent = userComponentFactory.create()
    }
}

After checking the actual code, I realized that the above code was slightly oversimplified. It might be nicer if simplification was implied in the explanation (e.g. use an ellipsis // …).

Define registrationComponent in the RegistrationActivity class in https://developer.android.com/codelabs/android-dagger#10

Field doesn't define in the RegistrationActivity class in
https://developer.android.com/codelabs/android-dagger#10

The registrationComponent filed not defined as a class field.
It may be confusable
Could you change from

class RegistrationActivity : AppCompatActivity() {
    ...
    override fun onCreate(savedInstanceState: Bundle?) {

to

class RegistrationActivity : AppCompatActivity() {
    lateinit var registrationComponent: RegistrationComponent
    ...
    override fun onCreate(savedInstanceState: Bundle?) {

Why is Dagger rarely seen in other example projects

First,Thanks for your nice work on this project,I like it
but
What confuse me is that I can hardly see Dagger in many google's android project.
I(maybe many others) want to know why for this,if it is recommend to use Dagger in Android Project
Looking forward to someone to solve my doubts,and thanks for that

Step 7 Provide context

In step 7 it goes into detail about how to provide a context
it tells us...
The way to pass it in is with a Component Factory and using the @BindsInstance annotation.

If I build straight after this i get the error...
android.content.Context cannot be provided without an @Provides-annotated method.

To fix this issue I annoted property in the class that context is used like so..

class SomeClass @Inject constructor( @ApplicationContext private val context: Context )

Adding Dagger to the project: code snapshot contains 'kotlin-android-extensions'

https://developer.android.com/codelabs/android-dagger#3
First code snapshot on that page still includes id 'kotlin-android-extensions', which give the following mistake:

The 'kotlin-android-extensions' Gradle plugin is no longer supported. Please use this migration guide (https://goo.gle/kotlin-android-extensions-deprecation) to start working with View Binding (https://developer.android.com/topic/libraries/view-binding) and the 'kotlin-parcelize' plugin.

Androidx ViewModel

I think this code lab could benefit from showing how to use Dagger with an Androidx ViewModel and ViewModelFactory.

@Component issue.

After adding @componet, I am getting issues.

Execution failed for task ':app:kaptDebugKotlin'.

A failure occurred while executing org.jetbrains.kotlin.gradle.internal.KaptWithoutKotlincTask$KaptExecutionWorkAction
java.lang.reflect.InvocationTargetException (no error message)

  • Try:

Run with --info or --debug option to get more log output.
Run with --scan to get full insights.

Please tell me where am I doing wrong.

Add workmanager

Could you add work manager and the standard way to inject dependencies to Worker?

Mistake in the In the 8. Injecting the graph into an Activity . Private with @Inject

In the 8. Injecting the graph into an Activity

MainActivity.kt

class MainActivity : AppCompatActivity() {

    // @Inject annotated fields will be provided by Dagger
    @Inject
    private lateinit var userManager: UserManager

    @Inject
    private lateinit var mainViewModel: MainViewModel

    ...
}

but Dagger does not support injection into private fields

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.