Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use angular 8 with webpack in rails 6 app?

I'm reading the ebook Rails, Angular, Postgres, and Bootstrap, Second Edition. I'm really learning a lot. The books it's from 2017, but I'm trying to create the project with all the frameworks updated. I want the hard way. hehehe

So I'm using Rails 6 and Angular 8. I got stuck when I tried to to create a component for angular inside the webpack. How?

I will only describe the steps that I think that it's necessary, so that's what I did:

I create the rails project with:

rails new angular-on-rails

Then I added the angular with webpacker:

rails webpacker:install:angular

After that I created a simple view:

rails g controller dashboard index

And then, inside this view, I added this code:

<hello-angular></hello-angular>
<%= javascript_pack_tag "hello_angular" %>

It works! I can see the Hello Angular in the browser.

After that I tried to create a component called hello-component:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'hello-component',
  template: `<h1>Hello component</h1>`
})
export class HelloComponent implements OnInit {

  constructor() { }

  ngOnInit() {
  }

}

console.log("Hello Component")

Not forgeting to update the app.module.ts:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { HelloComponent } from './hello-component/hello-component.component'

@NgModule({
  declarations: [
    AppComponent,
    HelloComponent
  ],
  imports: [
    BrowserModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

And the index.html.erb:

<hello-angular></hello-angular>
<hello-component></hello-component>
<%= javascript_pack_tag "hello_angular" %>

I can't see in the browser the Hello Component and there is no errors on the browser console, it shows only the console.log from the hello-component ts file. So the file is being loaded, but not rendering... What am I missing?

I put this simple project in a repository if you want to take a look.

Thank you for your time!

like image 606
Pedro Paiva Avatar asked Oct 15 '25 14:10

Pedro Paiva


2 Answers

To begin with angular and rails the easy way is to create a project from the scratch: I personally use rvm for ruby gem sets and version management, nvm (node version managemen), yarn and npm (javascript package managers)

At this moment, I think that is easy to integrate react than angular, because angular is a complet framework, not only a frontend library as React so react mix better, really with Angular you have two applications.

rails new testing_angular -B --webpackt=angular

after that, go inside the project

 cd testing_angular
 bundle install
 rails webpacker:install
 rails webpacker:install:angular

finally we have all the things to begin, go and work with your favorite text editor at this point I think that the nature of react mix better with rails than angular, but this is only my opinion.

Here you have the basic rails app, that you can run easily with

RAILS_ENV=development bundle exec rails server -b 0.0.0.0

and a complete angular app in app/javascript/hello_angular.

We need to call this app with a new controller

rails g controller hello_angular index

and add the necessary routes in /config/routes.rb

cat config/routes.rb
Rails.application.routes.draw do

  root 'hello_angular#index'
  get 'hello_angular/index'

end

change the view to render angular like this:

➜ cat app/views/hello_angular/index.html.erb
<div>
  <hello_angular></hello_angular>
</div>
<%= javascript_pack_tag 'hello_angular' %>

With this it should work but we need to fix some things before:

first:

add a file custom.js to config/webpack, in order

cat > config/webpack/custom.js
const webpack = require('webpack')
const path = require('path')
module.exports = {
  plugins: [
      new webpack.ContextReplacementPlugin(
        /angular(\\|\/)core/,
        root('../../app/javascript/hello_angular'), // location of your src
        { }
      )
  ]
}
function root(__path) {
  return path.join(__dirname, __path);
}

second edit development.js

➜ cat config/webpack/development.js
process.env.NODE_ENV = process.env.NODE_ENV || 'development'

const environment = require('./environment')
const {merge} = require('webpack-merge') // update from previous

const customConfig = require('./custom')

module.exports = merge(environment.toWebpackConfig(), customConfig)

then we need to add some dependecies:

yarn add webpack-merge

and I think that this are two bugs that we need to fix.

1) yarn add core-js@^2.5.0
if the project cannot load corejs/es7reflect
  1. ERROR Error: "The selector "hello-angular" did not match any elements"

You need to modfy this :

 cat app/javascript/hello_angular/app/app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'hello_angular', <= fix this selector
  template: `<h1>Hello {{name}}</h1>`
})
export class AppComponent {
  name = 'Angular!';
} 

Finally you can load the project:

RAILS_ENV=development bundle exec rails server -b 0.0.0.0

enter image description here

Started GET "/" for 127.0.0.1 at 2019-10-18 23:00:58 +0200
   (0.5ms)  SELECT sqlite_version(*)
Processing by HelloAngularController#index as HTML
  Rendering hello_angular/index.html.erb within layouts/application
[Webpacker] Compiling…
[Webpacker] Compiled all packs in /Users/toni/learn/ruby/ruby-way/angular-way/testing_angular/public/packs
  Rendered hello_angular/index.html.erb within layouts/application (Duration: 9940.3ms | Allocations: 4452)
Completed 200 OK in 12213ms (Views: 12208.3ms | ActiveRecord: 0.0ms | Allocations: 2022052)

then it really work as a pi lets preapre this endpoint, in routes add a route, and add a method to hello_angular controller

http://localhost:3000/hello_angular/world?name=Calimero

{

    "name": "Calimero"

}

and add the method to the controller created before:

class HelloAngularController < ApplicationController
  def index
  end

  
  def world
    name = params[:name] || 'world'
    render json: { name: name }
  end
end

then to render this in angular:

testing_angular on ξ‚  master [?] is πŸ“¦ v0.1.0 via β¬’ v12.4.0 via πŸ’Ž ruby-2.6.3@way took 39m 30s
➜ cat app/javascript/hello_angular/app/app.component.ts
import { Component } from '@angular/core';
import {HttpClient} from '@angular/common/http';

@Component({
  selector: 'hello_angular',
  template: `<h1>Hello {{name}}</h1>
             <button (click)="changeName()">Change Name!</button>`
})
export class AppComponent {
    name = 'Angular!';

  constructor(private http: HttpClient){}

  changeName() {
    this.http.get('/hello_angular/world').subscribe(data => {
      this.name = data['name'];
    });
  }
}

testing_angular on ξ‚  master [?] is πŸ“¦ v0.1.0 via β¬’ v12.4.0 via πŸ’Ž ruby-2.6.3@way
➜ cat app/javascript/hello_angular/app/app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import {HttpClientModule} from '@angular/common/http';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
      BrowserModule,
      HttpClientModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

finally you can have the angular app running, please check the ifnal reference and also the complete source code here:

https://github.com/anquegi/testing-angular

and please check this references:

  1. https://github.com/amitai10/rails-angular-webpacker
  2. https://medium.com/swlh/getting-started-with-rails-6-and-react-afac8255aecd[4]
  3. https://www.pluralsight.com/guides/react-vs-angular-2-integration-with-rails
like image 93
anquegi Avatar answered Oct 18 '25 05:10

anquegi


I think you need to add the HelloComponent also to the bootstrap array.

like image 35
Marco Roth Avatar answered Oct 18 '25 04:10

Marco Roth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!