Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

No provider for String

Hi can somebody tell Me what am I doing wrong? I think it's simple error, but I'm new to angular and I can't find it.

EXCEPTION: No provider for String! (SwNavItemCmp -> String)

export interface SwNavItemModel {
	name: string;
  route: string;
  children?: Array<SwNavItemModel>;
}

import {SwNavItemModel} from '../models/sw_nav_item_model';

export const NAV_ITEMS_DATA: Array<SwNavItemModel> = [
  { name: 'Home',
  	route: '/Home' },
  { name: 'Offer',
    route: '/Offer',
  	children: [
      { name: 'Prices',
      	route: '/Prices' },
      { name: 'Samples',
        route: '/Samples' }
    ]
  },
  { name: 'About',
    route: '/About',
    children: [
      { name: 'Us',
        route: '/Us' },
      { name: 'Projects',
        route: '/Projects' },
      { name: 'Skills',
        route: '/Skills' }
    ]
  },
  { name: 'Contact',
    route: '/Contact' }
];

import {Injectable} from 'angular2/core';
import {NAV_ITEMS_DATA} from '../data/mock_nav_data';


@Injectable()
export class NavService {
	getNavData() {
		return Promise.resolve(NAV_ITEMS_DATA);
	}
}

import {Component, OnInit} from 'angular2/core';
import {
ROUTER_DIRECTIVES
} from 'angular2/router';
import {SwNavItemCmp} from './sw-nav-item/sw_nav_item';
import {SwNavItemModel} from '../../../models/sw_nav_item_model';
import {NavService} from '../../../services/nav_service';

@Component({
  selector: 'sw-nav',
  templateUrl: './components/shared/sw-nav/sw_nav.html',
  styleUrls: ['./components/shared/sw-nav/sw_nav.css'],
  providers: [NavService],
  directives: [ROUTER_DIRECTIVES, SwNavItemCmp]
})
export class SwNavCmp implements OnInit {
  public items: Array<SwNavItemCmp> = [];

  constructor(private _navService: NavService) {
  }

  ngOnInit(): any {
    this.getNavData();
  }

  getNavData() {
      this._navService.getNavData().then((navData: Array<SwNavItemModel>) => {
          console.log(navData);
          console.log(Object.keys(navData));
          this.addItems(navData);
      });
  }

  addItem(name: string, route: string, children?: Array<SwNavItemModel>) {
    console.log();
    console.log('name: ' + name);
    console.log('route: ' + route);
    console.log('children: ' + children);
    if(children) {
      let childrenItems: Array<SwNavItemCmp> = [];
      console.log('childrenItems: ' + childrenItems);
      children.forEach((child) => {
        console.log('child: ' + child);
        childrenItems.push(new SwNavItemCmp(child.name, child.route, null));
        console.log('childrenItems: ' + childrenItems);
      });
      this.items.push(new SwNavItemCmp(name, route, childrenItems));
      console.log('Items: ' + this.items);
    } else {
      this.items.push(new SwNavItemCmp(name, route, null));
      console.log('Items: ' + this.items);
    }
  }

  addItems(itemsArray: Array<SwNavItemModel>) {
    console.log('ItemsArray: ' + itemsArray);
    itemsArray.forEach((item) => {
      console.log('item: ' + item);
      item.children ? this.addItem(item.name, item.route, item.children) : this.addItem(item.name, item.route, null);
    });
    console.log('Items: ' + this.items);
  }
}

import {Component, Input} from 'angular2/core';
import {ROUTER_DIRECTIVES} from 'angular2/router';


@Component({
  selector: 'sw-nav-item',
  templateUrl: './components/shared/sw-nav/sw-nav-item/sw_nav_item.html',
  styleUrls: ['./components/shared/sw-nav/sw-nav-item/sw_nav_item.css'],
  directives: [ROUTER_DIRECTIVES]
})
export class SwNavItemCmp {
	@Input() items: Array<SwNavItemCmp>;
  name: string;
  route: string;
  children: Array<SwNavItemCmp> = [];
  constructor(name: string, route: string, children?: Array<SwNavItemCmp>) {
    this.name = name;
    this.route = route;
    this.children = children;
  }
}
constructor(name: string, route: string, children?: Array) {...

throw error TS2314: Generic type 'Array<T>' requires 1 type argument(s).

//////////////////////////////////////////////////////////////

Now I have this:

sw_nav.ts

...
export class SwNavCmp implements OnInit {
  public items: Array<SwNavItemCmp> = [];
  ...
}

sw_nav.html

    <nav>
    <ul class="main-menu">
        <li *ngFor="#item of items">
            <sw-nav-item [items]="item.children"></sw-nav-item>
        </li>
    </ul>
</nav>

questions: -Should I pass whole item insted of item.children?

sw_nav_item.ts

import {Component, Input, Inject, Injectable} from 'angular2/core';
import {ROUTER_DIRECTIVES} from 'angular2/router';

@Component({
  selector: 'sw-nav-item',
  templateUrl: './components/shared/sw-nav/sw-nav-item/sw_nav_item.html',
  styleUrls: ['./components/shared/sw-nav/sw-nav-item/sw_nav_item.css'],
  directives: [ROUTER_DIRECTIVES]
})
@Injectable()
export class SwNavItemCmp {
  @Input() items: Array<SwNavItemCmp>;

  name: string;
  route: string;
  children: Array<SwNavItemCmp>;

  constructor(name, route, @Inject(SwNavItemCmp) children: Array<SwNavItemCmp>) {
    this.name = name;
    this.route = route;
    this.children = children;
  }
}

questions: -How should constructor looks like? I think it's invalid. -How to pass data from input to constructor? -Should I use Injector.resolveAndCreateChild() to assing children items?

sw-nav-item.html

???

questions: -How to render it recursive? I want to render all sw-nav-item be itself.

And main questions: -Where should I put var injector = Injector.resolveAndCreate(... provide(...), and how should it looks like? -If I have wrong structure or concept. How to do it right way? I mean recursive components creation and rendreing.

like image 676
Sakala Avatar asked Apr 01 '26 16:04

Sakala


1 Answers

Update

-How should constructor looks like? I think it's invalid.

The constructor should list the arguments you want to get passed in by Angulars dependency injection (DI). DI can pass values where it has a provider registered in bootstrap (bootstrap(AppComponent, [SomeProvider, ...]))

-How to pass data from input to constructor? -Should I use Injector.resolveAndCreateChild() to assing children items?

I don't know what you mean by "input" or "children items" here. You don't need Injector.resolveAndCreateChild()

-How to render it recursive? I want to render all sw-nav-item be itself.

I don't understand the question. How is that related to the constructor?

-Where should I put var injector = Injector.resolveAndCreate(... provide(...),

As mentioned above, you don't need that.

and how should it looks like? -If I have wrong structure or concept. How to do it right way? I mean recursive components creation and rendreing.

You don't need the constructor for this. If you want to pass data from parent to children use binding

<!-- in parent component -->
<some-element [someInput]="someValueFromParent">

@Component({
   selector: 'child-component',
})
export class ChildComponent {
  @Input() someInput;

  constructor() {
    // here Angular hasn't yet assigned the `someValueFromParent`
  }

  ngOnInit() [
    // here or in event handlers I can access `someInput` and
    // `someValueFromParent` is assigned
  }
}

Original

The name and route parameters have no providers.

constructor(name: string, route: string, children?: Array<SwNavItemCmp>) {

You can't have parameters in components constructors without telling DI what to pass in.

What's the purpose of these parameters?

like image 61
Günter Zöchbauer Avatar answered Apr 03 '26 15:04

Günter Zöchbauer



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!