I been trying to follow all the tutorials, and answers that I have found and I just can't make it work yet. Any help is appreciated it. I got this error:
Error: Provided data source did not match an array, Observable, or DataSource
And this is the JSON response I get from the server:
{receivedDate: "2018-05-22T00:00:00", id: "27280371", companyName: "Dark&Stormy", documentType: 11, receipts: Array(1), …}
And this is my code:
import { Component, OnInit } from '#angular/core';
import { FormBuilder, FormGroup, FormControl } from '#angular/forms';
import { HttpClient, HttpHeaders, HttpRequest, HttpEventType, HttpResponse } from '#angular/common/http';
import { Router, ActivatedRoute, ParamMap } from '#angular/router';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';
import { DataSource } from '#angular/cdk/collections';
import { MatPaginator, MatSort, MatTableDataSource } from '#angular/material';
import { myService } from './../../../api';
import { InputService } from './../input.service';
import { IReceipt } from './../models/receipt.model';
#Component({
selector: 'app-submission-details',
templateUrl: './submission-details.component.html',
styleUrls: ['./submission-details.component.css']
})
export class SubmissionDetailsComponent implements OnInit {
setPaymentMethodForm: FormGroup;
submissionList = [];
errorMessage: string;
private documentId;
receipt: IReceipt;
dataSource = new MatTableDataSource();
displayedColumnsReceipt = ['id', 'fromDate', 'pReference', 'pMethod', 'status', 'valid', 'receipt'];
constructor(
private client: myService.Client,
private fb: FormBuilder,
private inputService: InputService,
private router: Router,
private activatedRoute: ActivatedRoute
) {
this.createForm();
activatedRoute.data
.subscribe(
data => this.documentId = data[this.documentId]
);
}
id: string;
private document: any;
ngOnInit() {
this.activatedRoute.params.subscribe(params => {
if (params['id']) {
this.id = params['id'];
console.log('paramsId: ', this.id);
this.inputService.getDocumentId(this.id)
.subscribe(res => {
this.dataSource = res;
console.log('sub-details.res: ', res);
});
}
});
}
getSubmissionDetails(string): void {
this.client.apiSubmissionGetSubmissionDocumentGet('documentId')
.subscribe(
data => {
this.submissionList = this.submissionList;
console.log('data: ', data);
},
(error: any) => this.errorMessage = <any> error);
}
createForm() {
this.setMethodForm = this.fb.group({
documentId: '',
receiptType: ''
});
}
}
Here
this.dataSource = res;
Whats res? Is it array? If so then
this.dataSource.data = res;
Related
In order to make the data accessible through out the app, I created a new service called the DataService where I want to store my data coming from the API in a Subject.
While I do get the data, I cen see the array of objects in a log from DataService, my array in HomeComponent that should get the data is undefined in the console:
browser inspector console output
I imagine I have some stupid errors in my code, I am a beginer. Could you help me ?
HomeComponent:
import {Component, OnInit, Output} from '#angular/core';
import {DataService} from '../../shared/services/data.service';
import {Subscription} from 'rxjs';
import {Article} from '../../shared/models/article';
#Component({
selector: 'app-home',
templateUrl: './home.component.html',
styleUrls: ['./home.component.scss']
})
export class HomeComponent implements OnInit {
#Output() articles?: Article[];
articleSubscription?: Subscription;
constructor(private dataService: DataService) { }
ngOnInit(): void {
this.dataService.emitArticlesSubject(this.dataService.loadArticles());
this.articleSubscription =
this.dataService.articlesSubject.subscribe(
(articles) => {
this.articles = articles;
}
);
console.log('HOME COMPONENT: ngOnInit: this.articles : ' + JSON.stringify(this.articles));
}
}
DataService:
import { Injectable } from '#angular/core';
import {BehaviorSubject, Subject} from 'rxjs';
import {ArticleService} from './article.service';
import {Article} from '../models/article';
#Injectable({
providedIn: 'root'
})
export class DataService {
articles?: Article[];
message = 'Aucun résultat ne correspond à votre recherche.';
articlesSubject = new Subject<Article[]>();
constructor(private articleService: ArticleService) { }
emitArticlesSubject(action: any): void {
this.articlesSubject.next(action);
}
/**
* Method to be served as a parameter
* to the 'emitArticlesSubject' method
* to load articles sorted by date.
*/
loadArticles(): any {
this.articleService.getAll().subscribe(
data => {
this.articles = data._embedded.articles;
console.log('DataService: loadArticles() : ' + JSON.stringify(this.articles));
},
error => {
console.log('ERROR: DataService not able to loadArticles !' );
}
);
}
/**
* Method to be served as a parameter
* to the 'emitArticlesSubject' method
* to load articles sorted by last activity.
*/
loadArticlesByActivity(): any {
this.articleService.getAllSortedByActivity().subscribe(
data => {
this.articles = data._embedded.articles;
},
error => {
console.log('ERROR: DataService not able to loadArticlesByActivity');
}
);
}
}
ArticleService:
import { Injectable } from '#angular/core';
import {HttpClient, HttpHeaders} from '#angular/common/http';
import {Observable} from 'rxjs';
import {Article} from '../models/article';
import {ResponseEntities} from '../../core/ResponseEntities';
const baseUrl = 'http://localhost:8080/articles';
const queryUrl = '?search=';
const dateUrl = '?sort=date,desc';
#Injectable({
providedIn: 'root'
})
export class ArticleService {
constructor(private http: HttpClient) { }
getAll(): Observable<ResponseEntities<Article[]>> {
return this.http.get<ResponseEntities<Article[]>>(`${baseUrl}${dateUrl}`);
}
getAllSortedByActivity(): Observable<ResponseEntities<Article[]>> {
return this.http.get<ResponseEntities<Article[]>>(`${baseUrl}/${dateUrl}`);
}
search(term: string): Observable<ResponseEntities<Article[]>> {
return this.http.get<ResponseEntities<Article[]>>(`${baseUrl}/${queryUrl}${term}`);
}
get(id: any): Observable<Article> {
return this.http.get<Article>(`${baseUrl}/${id}`);
}
create(data: any): Observable<any> {
return this.http.post(baseUrl, data);
}
update(id: any, data: any): Observable<any> {
return this.http.put(`${baseUrl}/${id}`, data);
}
delete(id: any): Observable<any> {
return this.http.delete(`${baseUrl}/${id}`);
}
deleteAll(): Observable<any> {
return this.http.delete(baseUrl);
}
findByTag(tag: any): Observable<Article[]> {
return this.http.get<Article[]>(`${baseUrl}?tag=${tag}`);
}
}
The problem could be related to subscription in data service.
this.dataService.emitArticlesSubject(this.dataService.loadArticles());
in this line emitArticlesSubject() called. but loadArticles() subscribed to underlaying service. emitArticlesSubject() only call loadArticles() and does not wait for its subscription to get complete. that causes articlss to be undefined. you should use promise in loadArticles() or change your service structures and call ArticleService directly in your HomeComponent.
In your HomeComponent you are console logging the contents of this.articles before the articles have actually been fetched. If you want to log the articles after they have been fetched, you can console log in the subscription instead:
this.articleSubscription =
this.dataService.articlesSubject.subscribe(
(articles) => {
this.articles = articles;
console.log('HOME COMPONENT: ngOnInit: this.articles : ' + JSON.stringify(this.articles));
}
);
Good Afternoon,
I am trying to render the api data in a material table, but I am having issues connecting my NasaApiService to the dataSource array.
As of right now I am getting a "Type 'MatTableDataSource' is not assignable to type '[]'. error. Any help is much appreciated.
/*Nasa Service*/
import { Injectable } from '#angular/core';
import {HttpClient } from '#angular/common/http';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
export interface NasaStation {
name: string;
nametype: string;
id: string;
year: string;
recclass: string;
items: any;
}
#Injectable()
export class NasaApiService {
parsed: any;
constructor(private _http: HttpClient) {
}
getNasaData(): Observable<NasaStation> {
return this._http.get<NasaStation>('https://data.nasa.gov/resource/gh4g-9sfh.json');
}
}
/*nasa.component.*/
import { Component, OnInit } from '#angular/core';
import { NasaApiService} from '../nasa-api.service';
import {HttpClient} from '#angular/common/http';
import { MatTable,MatTableDataSource } from '#angular/material/table';
const api = 'https://data.nasa.gov/resource/gh4g-9sfh.json';
#Component({
selector: 'app-nasa',
templateUrl: './nasa.component.html',
styleUrls: ['./nasa.component.css']
})
export class NasaComponent implements OnInit {
data;
dataSource: [];
displayedColumns: string[] = ['Name', 'Name-type', 'ID', 'Year', 'Recclass'];
constructor(private _nasa: NasaApiService) {
}
ngOnInit(){
this._nasa.getNasaData().subscribe(data => {
this.dataSource = new MatTableDataSource(this.data);
this.data = data;
console.log(data);
})
}
}
ngOnInit(){
this._nasa.getNasaData().subscribe(data => {
this.data = data;
this.dataSource = this.data;
console.log(this.dataSource);
})
}
}
Was my final nasa.component code and I just passed datasource into Material Angular.
I create an application using Node.js and Angular9.
It is used to allow anyone to establish a company on the site. When an employee comes to create a
company, he presses on the site "create a company" and a form appears to put the company name,
address and domain for it, and when he presses the "create" button, this problem appears.
Knowing that the backend is NodeJs.
And when I create a company using Postman I don't have any problems.
The problem is only on the part of the Angular.
when I execute the code from the Angular side, I have this problem:
ERROR TypeError: Failed to execute 'setRequestHeader' on 'XMLHttpRequest': Value is not a valid ByteString
and this Error:
ERROR CONTEXT
This is the Code:
Company.server.ts:
import { Injectable } from '#angular/core';
#Injectable()
export class CompanyService {
constructor() { }
}
Company.server.spec.ts:
import { TestBed, inject } from '#angular/core/testing';
import { CompanyService } from './company.service';
describe('CompanyService', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [CompanyService]
});
});
it('should be created', inject([CompanyService], (service: CompanyService) => {
expect(service).toBeTruthy();
}));
});
data.service.ts:
import { Injectable } from '#angular/core';
import { Observable } from 'rxjs';
import { HttpClient, HttpParams, HttpHeaders } from '#angular/common/http';
import { platformBrowserDynamicTesting } from '#angular/platform-browser-dynamic/testing';
import { BoundDirectivePropertyAst } from '#angular/compiler';
#Injectable()
export class DataService {
constructor(private httpClient: HttpClient) { }
create_company(body): Observable<any> {
var reqHeader = new HttpHeaders({
'Authorization': localStorage.getItem('token'),
'Content-Type': 'application/json'
});
return this.httpClient.post<any>
('http://localhost:3001/employee/company', body, { headers: reqHeader });
}
Company.component.ts:
import { Component, OnInit } from '#angular/core';
import { Router } from "#angular/router"
import { DataService } from '../../_services/data.service';
#Component({
selector: 'app-company',
templateUrl: './company.component.html',
styleUrls: ['./company.component.css']
})
export class CompanyComponent implements OnInit {
newCompany = {
company: {
name: '',
address: '',
domain: ''
}
}
public id: string;
public name: string;
public roles: any;
public email: string;
public token: string;
constructor(private dataService: DataService, private router: Router) { }
createCompany() {
console.log(JSON.stringify(this.newCompany));
console.log(localStorage.getItem('token'));
this.dataService.create_company(JSON.stringify(this.newCompany)).subscribe((data) => {
console.log(data);
})
}
logout() {
localStorage.clear();
this.router.navigate(['/register']);
}
ngOnInit() {
this.roles = localStorage.getItem('roles');
console.log(this.roles);
this.id = localStorage.getItem('id');
this.name = localStorage.getItem('name');
this.email = localStorage.getItem('email');
this.token = localStorage.getItem('token');
localStorage.setItem('id', "14ll06y4kbne6x6g");
localStorage.setItem('name', "Dalida");
localStorage.setItem('email', "dalida#gmail.com");
localStorage.setItem('roles', JSON.stringify([
{
roleId: 3,
targetId: '0',
employeeId: '14ll08o4kbm7apn9'
},
{
roleId: 2,
targetId: '4',
employeeId: '14ll08o4kbm7apn9'
}
]));
localStorage.setItem('token', 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjE0b…
I2MH0.wHUoGDYqZIsty1DqUxUtkuQReBUidS4mC0MAQi1bMtQ');
}
}
How can I solve this problem?
I'm new to Angular 8 and wondering why im getting this error, also if you see a better way to write the following code please don't hesitate to give me tips.
Type 'Data' is missing the following properties from type 'Documentary': id, > title, slug, storyline, and 13 more.
The error is here in AdminDocumentaryEditComponent
ngOnInit() {
this.route.data.subscribe(data => {
this.documentary = data; //here
console.log(this.documentary);
this.initForm();
})
}
DataService
import { HttpClient, HttpParams } from '#angular/common/http';
import { Injectable } from '#angular/core';
import { throwError } from 'rxjs';
import { catchError } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class DataService {
constructor(private url: string, private http: HttpClient) { }
get(slug) {
return this.http.get(this.url + '/' + slug);
}
getAll(params:HttpParams) {
return this.http.get<Object[]>(this.url,
{
params: params
});
}
create(resource) {
return this.http.post(this.url, JSON.stringify(resource));
}
update(resource) {
return this.http.put(this.url + '/' + resource.id, JSON.stringify({
}));
}
delete(id: number) {
return this.http.delete(this.url + '/' + id);
}
}
DocumentaryService
import { HttpClient } from '#angular/common/http';
import { DataService } from './data.service';
import { Injectable } from '#angular/core';
#Injectable({
providedIn: 'root'
})
export class DocumentaryService extends DataService {
constructor(http: HttpClient) {
super('http://localhost:8000/api/v1/documentary', http);
}
}
DocumentaryResolverService
import { Documentary } from './../models/documentary.model';
import { DocumentaryService } from './documentary.service';
import { Injectable } from '#angular/core';
import {
Resolve,
ActivatedRouteSnapshot,
RouterStateSnapshot
} from '#angular/router';
#Injectable({ providedIn: 'root' })
export class DocumentaryResolverService implements Resolve<Documentary> {
constructor(private documentaryService: DocumentaryService) {}
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
let slug = route.params['slug'];
let documentary = this.documentaryService.get(slug)[0];
return Object.assign(new Documentary(), documentary);
}
}
AdminDocumentaryEditComponent
import { Documentary } from './../../../models/documentary.model';
import { DocumentaryService } from './../../../services/documentary.service';
import { Params, ActivatedRoute, Router } from '#angular/router';
import { Component, OnInit, ViewChild, ChangeDetectorRef } from '#angular/core';
import { FormArray, FormControl, FormGroup, Validators } from '#angular/forms';
import { AngularEditorConfig } from '#kolkov/angular-editor';
#Component({
selector: 'app-admin-documentary-edit',
templateUrl: './admin-documentary-edit.component.html',
styleUrls: ['./admin-documentary-edit.component.css']
})
export class AdminDocumentaryEditComponent implements OnInit {
documentary: Documentary;
editDocumentaryForm: FormGroup;
constructor(
private route: ActivatedRoute,
private documentaryService: DocumentaryService,
private router: Router,
private cd: ChangeDetectorRef) {}
editorConfig: AngularEditorConfig = {
editable: true,
spellcheck: true,
height: '25rem',
minHeight: '5rem',
placeholder: 'Enter text here...',
translate: 'no',
uploadUrl: 'v1/images', // if needed
};
ngOnInit() {
this.route.data.subscribe(data => {
this.documentary = data;
console.log(this.documentary);
this.initForm();
})
}
initForm() {
let title = this.documentary.title;
let slug = this.documentary.slug;
let storyline = this.documentary.storyline;
let summary = this.documentary.summary;
let year = this.documentary.year;
let length = this.documentary.length;
let status = this.documentary.status;
let short_url = this.documentary.short_url;
let poster = this.documentary.poster;
this.editDocumentaryForm = new FormGroup({
'title': new FormControl(title, [Validators.required]),
'slug': new FormControl(slug, [Validators.required]),
'storyline': new FormControl(storyline, [Validators.required]),
'summary': new FormControl(summary, [Validators.required]),
'year': new FormControl(year, [Validators.required]),
'length': new FormControl(length, [Validators.required]),
'status': new FormControl(status, [Validators.required]),
'short_url': new FormControl(short_url, [Validators.required]),
'poster': new FormControl(poster, [Validators.required])
});
this.editDocumentaryForm.statusChanges.subscribe(
(status) => console.log(status)
);
}
onFileChange(event) {
let reader = new FileReader();
if(event.target.files && event.target.files.length) {
const [file] = event.target.files;
reader.readAsDataURL(file);
reader.onload = () => {
this.editDocumentaryForm.patchValue({
poster: reader.result
});
// need to run CD since file load runs outside of zone
this.cd.markForCheck();
};
}
}
onSubmit() {
console.log(this.editDocumentaryForm);
}
}
In routing make sure to name resolver with the same name 'data':
{ path: 'somepath', component: AdminDocumentaryEditComponent, resolve: { data: DocumentaryResolverService} }
when I try to test the app in Ionic serve command, I didn't get any error. But when i try to publish the app, I get the error as "property json does not exist on type object" . The error takes place during the transpile stage:
How to solve this problem? I tried with every possibility, but i didn't get my problem solved.
Home.ts
import { Component } from '#angular/core';
import { NavController } from 'ionic-angular';
import { WeatherProvider } from '../../providers/weather/weather';
import { Storage } from '#ionic/storage';
//import { Response } from '#angular/http';
//import 'rxjs/add/operator/map';
#Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {
weather:any;
location:{
city:string,
state:string
}
constructor(
public navCtrl: NavController,
private weatherProvider:WeatherProvider,
private storage: Storage) {
}
ionViewWillEnter(){
this.storage.get('location').then((val)=>{
if(val!=null){
this.location = JSON.parse(val);
}else{
this.location = {
city: 'Chennai',
state: 'TN'
}
}
this.weatherProvider.getWeather(this.location.city,this.location.state)
// .map((res: Response) => res.json() )
.subscribe(weather => {
this.weather = weather.current_observation;
});
});
}
}
Weather.ts
import { HttpClient } from '#angular/common/http';
import { Injectable } from '#angular/core';
//import { Response } from '#angular/http';
//import 'rxjs/add/operator/map';
//import 'rxjs/Rx';
#Injectable()
export class WeatherProvider {
apiKey = '6d3243fb22b01d0c';
url;
constructor(public http: HttpClient) {
console.log('Hello WeatherProvider Provider');
this.url = 'http://api.wunderground.com/api/'+this.apiKey+'/conditions/q';
}
getWeather(city, state){
return this.http.get(this.url+'/'+state+'/'+city+'.json')
// .map(res => res.json());
// .map((res: Response) => res.json() );
}
}
Typescript is all about typing. So you should state the type of object you'are receiving from the method getWeather. Start by creating a class Weather at the end of home.ts (look below)
class Weather {
current_observation: string;
}
and make this change:
this.weatherProvider.getWeather(this.location.city,this.location.state)
// .map((res: Response) => res.json() )
.subscribe((weather: Weather) => {
this.weather = weather.current_observation;
});
});
}
ionViewWillEnter(){
this.storage.get('location').then((val) => {
if(val != null){
this.location = JSON.parse(val);
} else{
this.location ={
city: 'miami',
state: 'FL'
}
}
//Try below code
this.weatherprovider.getweather(this.location.city, this.location.state).subscribe(result => {
let weather:any = result;
this.weather = weather.current_observation;
console.log(this.weather);
});
});
}