Como usar o Signal do Angular 16 - Obter array do Back-end em Java

Olá, boa tarde. Recentemente estou aplicando os conseitos de signal em um projeto que estou desenvolvendo. Mas estou tendo problema ao obter e exibir os dados em um template. No caso ao usar o signal era pra varievel productsSgnal ser chamada e reconhecida como uma função no template como esta exposto, mas aparece um erro no console do navegador dizendo que productsSgnal não é reconhecido como uma função.Ou seja parece que o signal não funciona. Estou usando O PrimeNG no template.Se alguem souber resolver esse caso, desde já agradeço.

Estarei mostrando os detalhes do código:


@Component({
    selector: 'app-products-table',
    templateUrl: 'products-table.component.html',
    styleUrls: ['products-table.component.scss'],
    providers: [MessageService, ConfirmationService],
    
})
export class ProductsTableComponent implements OnInit{


    private productsService = Inject(ProductsService);
    public productsSgnal = this.productsService.productsSgnal;

}

@Injectable({
  providedIn: 'root',
})
export class ProductsService {

  httpOptions = {
    headers: new HttpHeaders({
      'Content-Type': 'application/json',
      'Authorization': 'Bearer ' + localStorage.getItem('token')
    })
  };
  public http = inject(HttpClient);

  public productUrl =  AppConstants.getbaseUrlPath +'product/';

  private product$ = this.http.get<GetAllProductsResponse[]>(this.productUrl,this.httpOptions)

  public productsSgnal = signal(this.product$);

}


    <p-table
        #dt
        [value]= "productsSgnal()"
        [rows]="10"
        [paginator]="true"
        [globalFilterFields]="['name', 'country.name', 'representative.name', 'status']"
        [tableStyle]="{ 'min-width': '75rem' }"
        [(selection)]="selectedproductss"
        [rowHover]="true"
        dataKey="id"
        currentPageReportTemplate="Showing {first} to {last} of {totalRecords} entries"
        [showCurrentPageReport]="true"
    >```

O input value de <p-table> espera receber um array, mas vc está tentando passar um signal que retorna um Observable<GetAllProductsResponse[]>.

Uma forma de alcançar o que vc quer seria usar o pipe async, assim:

[value]="(productsSgnal() | async) ?? []"

O operador ?? é necessário porque o async pode retornar null, então se isso acontecer, um array vazio é usado.

Mas vou te dizer uma coisa… Eu não tenho certeza, porque eu também ainda estou entendendo os casos de uso, mas eu acho que vc está usando o signal da maneira errada.

Acredito que o seu ProductsService deveria ter um método chamado getProducts() que vai invocar o método get do HttpClient normalmente, como vc faz sempre mesmo.

E o seu ProductsTableComponent ficaria assim:

export class ProductsTableComponent implements OnInit {
  private productsService = inject(ProductsService);
  public productsSgnal = signal<GetAllProductsResponse[]>([]);

  ngOnInit(): void {
    this.productsService
      .getProducts()
      .subscribe((products) => this.productsSgnal.set(products));
  }
}

Desta forma na sua <p-table> ficaria assim: [value]="productsSgnal().

Eu acho que cada componente tem que ter o seu próprio signal. Não acho que ele deva ser criado no service para ser compartilhado por todos.

1 curtida

Olá amigo, funcionou. Voce tinha razão. O Signal é feito para mudança de estado, com isso cada componente tem que ter o seu. E o metodo padrão getProducts tem que existir também. Eu removi porque estava seguindo um Tutorial, era como um exemplo de teste. Eu estou Migrando do Angular 15 para o 16. E estou implementando um projeto que tinha feito do Angular 15 e implementando os Signals. Com isso, já dar pra ter uma ideia como vai ficar os CRUD com os Signals. Obrigado.:slight_smile:

1 curtida