Where are the Angular developers?

Just wondering if there are are Angular developers on this forum, I’m currently learning Angular and it would be nice to know if I can come to this forum to ask some questions.

I don’t recall seeing a topic Angular related here, and I guess that’s not surprising considering the curriculum teaches React.

1 Like

I’m an Angular developer.

2 Likes

Not strictly, but I work with it a lot

I’m an Angular dev, and welcome anyone wanting to learn Angular in general. I’m pretty active for run of the mill questions on Angular’s gitter channel, good place if your getting going and want advice, or need help with open ended questions most of the time.

Angular’s a feature rich framework, which is great since its so powerful, but learning all the features does make it much harder to learn.

Goodluck and welcome to Angular :smiley:

1 Like

That’s great, I think I’d have more luck on those channels asking Angular related questions than on this forum honestly.

Right now I’m having difficulties understanding BehaviorSubject

Angular developer here. Do you need help understanding BehaviorSubject?

I think of BehaviorSubjects as Observables with which you can cache values, specifically the last emitted value.

Hard to know what to clarify without knowing the specifics of your difficulties in understanding this concept.

@WebDevCoach, @psychometry

I have implemented this authentication logic that I borrowed from an article I found online, this is for Ionic, but Ionic is built on Angular so I’m assuming everything is almost pretty much the same.

export class AuthenticationService {
  authenticationState = new BehaviorSubject(false);

  constructor(private storage: Storage, private plt: Platform) {
    // Check if token is stored when the device is ready
    this.plt.ready().then(readySource => {
      this.checkToken();
    });
  }

  checkToken() {
    this.storage.get(TOKEN_KEY).then(res => {
      if (res) {
        this.authenticationState.next(true);
      }
    });
  }

  login(cookie) {
    console.log("Login");
    return this.storage.set(TOKEN_KEY, cookie).then(() => {
      this.authenticationState.next(true);
    });
  }

  logout() {
    return this.storage.remove(TOKEN_KEY).then(() => {
      this.authenticationState.next(false);
    });
  }

  isAuthenticated() {
    return this.authenticationState.value;
  }
}

The authenticationState variable purpose is to condition my app based on whether the user is authenticated or not. If the user is authenticated I don’t want the user to go through the login screen, instead he/she should go directly to the home screen.

My app.component.ts

@Component({
  selector: "app-root",
  templateUrl: "app.component.html"
})
export class AppComponent {
  constructor(
    private platform: Platform,
    private splashScreen: SplashScreen,
    private statusBar: StatusBar,
    private authService: AuthenticationService,
    private router: Router
  ) {
    this.initializeApp();
  }

  initializeApp() {
    this.platform.ready().then(() => {
      this.statusBar.styleDefault();
      this.splashScreen.hide();

      this.authService.authenticationState.subscribe(state => {
        console.log("Auth state: " + state);
        if (state) {
          this.router.navigate(["home"]);
        } else {
          this.router.navigate(["login"]);
        }
      });
    });
  }
}

This code works, but there’s a small bug, even if the user is already authenticated the initial value of this variable is always false (Because initially is set to false) and therefore there’s a flicker effect for about half a second, the user opens up the app and the login screen shows up and then quickly changes to the home screen (if the user is authenticated). Instead, as soon as the user opens up the app they should see the home screen immediately

I know in React this would be possible conditioning the routes based on some property of the state object in the root of my app, but I’m not sure how how to do this in Angular.

I’m also not sure what’s the purpose of BehaviorSubject, what is it that it’s doing? Why is it needed here?

Can’t I just use a regular variable and set it to false, change it to true when the user is authenticated and then tell my app to render home screen if it’s true and login if it’s false?

Typically In Angular, you put your initialization logic in the ngOnInit life cycle hook not in the class constructor. This has to do with the way classes and components differ in Angular and how the life cycle is executed.

You are also injecting a few dependencies I am not familiar with. Are you injecting components or classes? It seems odd to me.

However, neither are related to your question about behavior subject, rather more to do with not following the convention of the framework.

In this case, the use of behavior subject is a way to always have a “current value” in hand for authentication status. It also serves the purpose of having something that will propagate change and broadcast the value when needed.

Multiple component could rely on the state of your auth variable, but using a regular variable does not allow all the components to know and react to changes to that variable. By using a behavior subject, you can update the value asynchronously and allow all the component that relies on that value receive the update and trigger their own changes.

There are some concept in play with Angular that doesn’t necessarily have equivalent in React and the pervasive use of reactive programming, in particular Observable and Subjects is one. Dependency Injection is another. I would go through some documentations for both Angular and Rxjs to learn more about these concepts and conventions of the framework

This is a rather broad stroke answer, as I cannot really debug your code through just snippets.

Umm so if I understand this correctly, using BehaviorSubject would be similar to having state in the root of your parent component of a React app, then having your children components react to the value of the state object?

let’s say I have a service.ts where all I do is to get a list of posts from the server and I have 2 components that need to keep track of these posts. In component A I render the list of posts I get from the server, in component B I have a function to remove the first element of the array of posts, and when I do the component A should update. In an case like this, do I need to use BehaviorSubject to keep the data synced between the components? Storing the posts in a regular variable wouldn’t work in this situation?

Typically In Angular, you put your initialization logic in the ngOnInit life cycle hook not in the class constructor. This has to do with the way classes and components differ in Angular and how the life cycle is executed.

Are there any significant differences in initializing data in the ngOnInit() method and not in the constructor? Or is this more like a community convention thing?

I investigated a bit and it seems it’s best practice to keep the constructor light weight and use ngOnInit for initialization and http requests.

@Inputs to components will not be “given” by angular in the constructor . Where as they will exist during the ngOnInit lifecycle event.

If we think about when the constructor is called, it is called by Angular when it is initializing your component classes, so it is called before angular can set anything else up.

The ngOnInit method is called when the component is finished setting up (ref) by Angular to tell the component “your ready to go”


So you can do stuff in the constructor, but to prevent inconsistencies when building components, and getting confused as to what @Inputs are available, just do what you want in the ngOnInit method, that’s what its for.

I personally never do anything in the constructor. I leave the constructor to declare services/injectables.

1 Like

OMG man, great explanation and now that I think about it, this may be the reason why I have a small bug in my app because I’m initializing some data in the constructor of app.component.ts, I’ll try using the OnInit lifecycle method instead and see if that fixes the issue.

Thanks.

Think of your services as independent from your graphical components, kind of like Redux state management is independent of the presentation components. It’s there to help you manage and access data so you don’t need to fetch and cache the data with the view layer. It is de-coupled, data and view.

You don’t necessarily need to use Behavior Subject. Like Vanilla JS or React, there are ways to keep the data sync, but you’d be wasting a lot of conveniences that the framework affords you and doing a lot of work to reinvent the wheel. ANgular is a framework, which means to work with it smoothly, you have to give up some control and do things the Angular way.

In your hypothetical case, a simple observable would probably do, since there is no reason for you to cache the data within your application. The data is on the server. You can create an observable of the data and have both A and B subscribe to the observable. Whenever A or B subscribes to the observable, this could happen in any part of the component lifecycle, it picks up the latest version of the data stream, which is fetched from the server.

Honestly, these are concepts better explained through little projects rather than verbally.

Before you jump head-on into writing a full angular app, I’d highly recommend you go through the tutorial on the Angular official site https://angular.io/ and also familiarize yourself with reactive programming with http://reactivex.io/

Angular is only superficially similar to React, underneath the concepts and implementation are very different. The learning curve is probably pretty steep, but it is also very powerful and convenient to write once you understand some of its core concepts.

@psychometry, I think I might need an Observable or BehaviorSubject but not sure how to do it because I don’t fully these concepts just yet, let me explain the situation.

I have a authentication service with some methods, the one that matters for my example is login()

export class AuthenticationService {
  authenticationState = new BehaviorSubject(false);
  errorMessage: string;

  constructor(
    private storage: Storage,
    private plt: Platform,
    private http: HttpClient,
    private loadingController: LoadingController
  ) 
  async login(username, password) {
    const loading = await this.loadingController.create({
      duration: 2000,
      message: "Please wait..."
    });

    loading.present();

    this.http
      .post(apiEndPoint + "/jwt-auth/v1/token", {
        username,
        password
      })
      .subscribe(
        res => {
          console.log(res);
          loading.dismiss();
          this.storage
            .set(TOKEN_KEY, res["token"])
            .then(() => this.authenticationState.next(true));
        },
        ex => {
          loading.dismiss();
          console.log(ex);
          this.errorMessage = "Invalid username or password.";
        }
      );
  }
}

The piece of code that I care about is this.errorMessage which I am setting to a string when there is an error (or exception), I declared this variable at the top as you probably noticed.

The thing is, that I would like to use the value that I assigned to the errorMessage variable after the error occurs

I have it in my login.ts file

export class LoginPage implements OnInit {
  constructor(
    private authService: AuthenticationService,
    private navCtrl: NavController 
  ) {}

  errorMessage = this.authService.errorMessage;
}

Then I am trying to use the value of this variable to show an error in the UI in my login.html file

<div *ngIf="errorMessage">
    {{ errorMessage }}
  </div>

But nothing is displayed because the initial value is null and I suppose I am not keeping track of the changes. I know that I didn’t explain myself well enough here, but hopefully you guys get what I am trying to do. This is a very important concept that I need to learn before moving because I am sure I am going to need this technique in the future.

Oh woa, I think I solved it using BehaviorSubject:

errorMessage = new BehaviorSubject("");

Then if there is an error:

 ex => {
          loading.dismiss();
          console.log(ex);
          this.errorMessage.next("Invalid username or password.");
        }
<div *ngIf="errorMessage">
    {{ errorMessage.value }}
  </div>

Not sure if this would be the right way to do this, but it seems that it’s working so far. I think I am understanding now what are BehaviorSubjects used for.

So you might actually be complicating things using async await and what seems like you injecting some sort of view component inside of the service as loading controller. Are you following some sort of course or tutorial? The code structure seems a little unconventional to me.

  1. Observable is already similar to Async/Await, try to not mix it.

  2. Do anything related to view and DOM manipulation in a component.

For example, your login function can just simply be

login(username, password): Observable<any> {
return this.http.post(apiEndPoint + "/jwt-auth/v1/token", {username, password })
}

That function returns an observable which doesn’t go hot until you subscribed to it.

You can then subscribe to the observable and do this logic in your login component

this.authService.login(username, password).subscribe(
        res => {
          console.log(res);
          loading.dismiss();
          this.storage
            .set(TOKEN_KEY, res["token"])
            .then(() => this.authService.authenticationState.next(true));
        },
        ex => {
          loading.dismiss();
          console.log(ex);
          this.errorMessage = "Invalid username or password.";
        }
      );)

on the view side you can just use an async pipe in conjunction with an observable variable to determine what needs to be displayed, like

<div *ngIf="(isLoggedIn$ | async); else noAuth">
This only renders if the value returned by the isLoggedIn$ observable when subscribed is true
</div>

<ng-template #noAuth>
    <div>
        This only renders if the value returned by the isLoggedIn$ observable when subscribed is false
    </div>
</ng-template>

isLoggedIn$ can be the behavior subject this.authService.authenticationState.asObservable()

I’m actually breaking a lot of encapsulation conventions here myself, but I’m just giving you an example how the code can be simpler with just Angular conventions and how Observable can behave like async await. I’d recommend you read a more well rounded implementation online like http://jasonwatmore.com/post/2018/10/29/angular-7-user-registration-and-login-example-tutorial and really dig into it rather than the example I typed up on the fly.

I am not following a tutorial, although I got the bare structure for the authentication logic from a post I found online and used that as a blueprint.

I actually had my code similar to your example, but I decided to handle everything in the authentication service because I want the user to login upon registration and I have no control over the back-end to add the logic there. So instead of repeating the logic for login twice I implemented all the login logic in one method in the auth service and then call that method whenever I need it (login and register).

So for example this is my login method in auth service:

  async login(username, password) {
    const loading = await this.loadingController.create({
      duration: 5000,
      message: "Please wait..."
    });

    loading.present();

    return this.http
      .post(apiEndPoint + "/jwt-auth/v1/token", {
        username,
        password
      })
      .subscribe(
        res => {
          console.log(res);
          loading.dismiss();
          this.storage
            .set(TOKEN_KEY, res["token"])
            .then(() => this.authenticationState.next(true));
        },
        ex => {
          loading.dismiss();
          console.log(ex);
          this.errorMessage.next("Invalid username or password.");
        }
      );
  }

Then I call it in the login.ts

onSubmit(form) {
    this.authService.login(form.value.username, form.value.password);
  }

And also in my register function in my user service (because I want the user to login upon registration):

  register(user) {
    console.log(user);
    this.http
      .post(apiEndPoint + "/wp/v2/users/register", {
        username: user.username,
        email: user.email,
        password: user.password
      })
      .subscribe(
        res => {
          console.log(res);
          this.authService.login(user.username, user.password);
        },
        ex => console.log(ex)
      );
  }

This was the only way I could think of for not repeating myself twice with the login logic.

And yes, I should probably avoid mixing async and await with Observables, I’ll see what I can do, I reckon it seem a bit messy (although it works).

I am not going to lie, it bothers a me a bit that the Angular team went with Observables for http requests, why not just use Promises like everyone else :confused:

Actually Observables, Async/Await are all just promises underneath.

Once you learn it, you’ll find the Observable is a very powerful pattern and superior to plain promises. For example, you can cancel observables. You can merge, concat and switch Observable streams. It really simplifies and enable you to do neat reactive things. The Angular material table is a good example of using reactive programming.


I want to open angular form in separet window,
I wrote, tha last <li :

        <%--<li class="listCats"><a href="http://localhost:4200/HargalKriaClient?FirstName=<%=FirstName%> + &LastName=<%=LastName%> + &CompanyName=<%=CompanyName%>"  target="_blank">פתיחת קריאה - חדש</a></li>--%><!--1005694 good-->
        <li class="listCats"><a href="http://localhost:4200/HargalKriaClient?FirstName=<%=Session("FirstName")%> + &LastName=<%=Session("LastName")%> + &CompanyName=<%=Session("companyName")%>"  target="popup" ,"width=600","height=400">פתיחת קריאה - חדש</a></li><!--1005694 -->



I try also _blank
Help will be appreciated.
rami