4

I have the following code, which I am using to create a Casino Management System:

import { Component, OnInit } from '@angular/core';
import { Router }            from '@angular/router';
import { Observable }        from 'rxjs/Observable';
import { Subject }           from 'rxjs/Subject';

import { SearchService } from './search.service';
import { Data } from './datatypings';

@Component({
  moduleId: module.id,
  selector: 'casino-search',
  templateUrl: 'search.component.html',
  styleUrls: [ 'search.component.css' ],
  providers: [SearchService]
})

export class SearchComponent implements OnInit {

  data: Observable<Data[]>;

  private searchTerms = new Subject<String>();

  constructor(
    private searchService: SearchService,
    private router: Router) {}
  // Push a search term into the observable stream
  search(term: string): void {
    this.searchTerms.next(term);
  }

  ngOnInit(): void {
    this.data = this.searchTerms
      .debounceTime(150)        // wait for 150ms pause in events
      .distinctUntilChanged()   // ignore if next search term is same as previous
      .switchMap(term => term   // switch to new observable each time
        // return the http search observable
        ? this.searchService.search(term)
        // or the observable of empty data if no search term
        : Observable.of<Data[]>([]))
          .catch(error => {
        // TODO: real error handling
        console.log(error);
        return Observable.of<Data[]>([]);
      });
  }

  gotoDetail(data: Data): void {
    let link = ['/detail', data.id];
    this.router.navigate(link);
  }
}

However, when I attempt to transpile this code from TypeScript to JavaScript I get this error:

app/data/search.component.ts(37,37): error TS2345: Argument of type 'String' is not assignable to parameter of type 'string'.
  'string' is a primitive, but 'String' is a wrapper object. Prefer using 'string' when possible.

Now, I've fixed the error simply by changing String to string within the angle braces but I want to be able to proceed in future without creating similar errors, and also to write the best code I can... So I'm wondering if someone could clear this up for me:

I think I understand that a parameter with a wrapper class is something which encapsulates a primitive class and provides some sort of additional, usually interfacing related, behaviour (correct me if I'm wrong here), and I see why it might then not be possible to assign the contents of what is essentially a broader declared variable type to the more simple primitive, there is another aspect of the error message which interests me, that is:

Why would it be preferable to use type 'string' over type 'String' in Angular2/Typescript in such a general sense as the error seems to imply? What is it which makes this preferential?

4
  • try to change it to new Subject<string>(); "small s" Commented Oct 23, 2016 at 14:22
  • Yeah, I changed it before I asked the question. What I wanted to know, though, is what makes the predefined wrapper class String preferable over the primitive string type, as per the recommendation in the error message. Commented Oct 23, 2016 at 14:48
  • Did you find the solution ? I am facing the same problem. Commented Nov 15, 2016 at 10:09
  • Not at the moment, but I'm going to a small conference soon (giving a talk! Wooottt!) and the topic will be Angular2 and TypeScript, so I'll ask around and see if anyone knows the solution. Commented Nov 15, 2016 at 13:53

1 Answer 1

7
private searchTerms = new Subject<String>();

change it to

private searchTerms = new Subject<string>();

String is a class and string is a datatype.

Sign up to request clarification or add additional context in comments.

4 Comments

Yeah, I know. What is the difference between the Typescript library class String and the TypeScript datatype string which should cause me to use the datatype over the class in all instances where such a thing is possible (as per the error message), though, was my question.
Subject method/API will emit data later on. Subject<string>() so it tells which type of data will be emited. Generally subject can emit string type data and obviously not String class type data. So...
So it's preferable use the String wrapper class in general because the extra data in the wrapper class does not interface cleanly (or perhaps at all? I wonder if the wrapper class can be 'made' to interface, but that's seperate...) Subject API? Perhaps there is a more general rule about not adding additional complexity by using a wrapper class unless absolutely required and the Subject method issue is just one example of one wrapper class (I assume Subject is also a wrapper class?) interfacing poorly or not at all because of the additional complexity added by the wrapper?
its hard to say until looking inside of subject's definition.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.