I can't get item from Firebase Realtime Database with Axios and NestJS.
My code is:
import { Injectable } from '#nestjs/common';
import { HttpService } from '#nestjs/axios';
import { Observable } from 'rxjs';
import { AxiosResponse } from 'axios';
#Injectable()
export class AppService {
constructor(private httpService: HttpService) {}
async getHello(): Promise<Observable<AxiosResponse<any>>> {
const data = await this.httpService.get(
'[my firebase url.]',
).pipe();
return data;
}
}
I get this error:
[Nest] 5104 - 01.11.2021 20:28:19 ERROR [ExceptionsHandler] Converting circular structure to JSON
--> starting at object with constructor 'ClientRequest'
| property 'socket' -> object with constructor 'TLSSocket'
--- property '_httpMessage' closes the circle
TypeError: Converting circular structure to JSON
--> starting at object with constructor 'ClientRequest'
| property 'socket' -> object with constructor 'TLSSocket'
--- property '_httpMessage' closes the circle
at JSON.stringify (<anonymous>)
at stringify (C:\Users\Faruk\Desktop\projects\fbase\node_modules\express\lib\response.js:1123:12)
at ServerResponse.json (C:\Users\Faruk\Desktop\projects\fbase\node_modules\express\lib\response.js:260:14)
at ExpressAdapter.reply (C:\Users\Faruk\Desktop\projects\fbase\node_modules\#nestjs\platform-express\adapters\express-adapter.js:32:57)
at RouterResponseController.apply (C:\Users\Faruk\Desktop\projects\fbase\node_modules\#nestjs\core\router\router-response-controller.js:14:36)
at C:\Users\Faruk\Desktop\projects\fbase\node_modules\#nestjs\core\router\router-execution-context.js:175:48
at processTicksAndRejections (internal/process/task_queues.js:95:5)
at C:\Users\Faruk\Desktop\projects\fbase\node_modules\#nestjs\core\router\router-execution-context.js:47:13
at C:\Users\Faruk\Desktop\projects\fbase\node_modules\#nestjs\core\router\router-proxy.js:9:17
Looks like you aren't mapping the response at all. Axios responses are, by definition, circular, so you need to return only the part of the response you need. Most of the time, this is simply just return this.httpService.get(url).pipe(map((resp) => resp.data))
Related
I am new prisma / nextjs user and I am trying to understand how to unit test an API route that uses prisma. I have read the unit testing guide.
I like the dependency injection approach and have started trying to implement it. However I am struggling with the following development issue. Can anybody help?
With the dependency injection approach the unit testing guide explains how to setup the mock context and use this in the data access layer. Does anyone have any examples of how and where the real context could be initialised and used with an API route that uses a repository pattern? Is it possible to expand the next.js api handler with middleware to include the context to facilitate testing?
import type { NextApiRequest, NextApiResponse } from 'next'
import { PublishRepository } from '../../../repository'
// PUT /api/publish/:id
export default async function handle(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method == 'PUT') {
const postId = req.query.id;
let repo = new PublishRepository( // where does the live context come from and how is it initialised??? )
const post = repo.set_published(postId)
res.json(post);
}
}
Repository - Initialised using Context instance - How is this initialise for development and how is it mocked?
import { Post, PrismaClient } from "#prisma/client"
import { Context } from "../context"
import prisma from "lib/prisma"
export class PublishRepository {
private prisma: PrismaClient
constructor(context: Context) {
this.prisma = context.prisma
}
async set_published(post_id: string | string[]): Promise<Post> {
return await prisma.post.update({
where: { id: Number(post_id) },
data: { published: true },
});
}
}
Why we cant use an decorator within a NestJS service? Here is a example on how I tried to do, but it does not work.
Decorator: #User()
// user.decorator.ts
import { createParamDecorator } from '#nestjs/common';
export const User = createParamDecorator((data, req): {userId, email} => {
return data ? req.user[data] : req.user;
});
When I call this decorator into a service, I got this message: Unable to resolve signature of property decorator when called as an expression
// connect.service.ts
import { Injectable, Inject } from '#nestjs/common';
import { User } from '../account/user/user.decorator';
#Injectable()
export class ConnectService {
#User()
userInfo;
}
It looks like you are trying to add a decorator on an Injectable() I don't think you can do that. It would need to be on a method so that when it is called some magic can happen behind the scenes. Consider using class-validator and the validationPipe
For example:
#Get('vitalsByEncounterID')
async getVitalsByEncounterID(#Query() params: VitalsByEncounterPathDTO, #Headers(DFDHeaders.xRequestId) requestId: string): Promise<VitalSignsDTO[]> {}
Then you'd decorate the class
export class VitalsByEncounterPathDTO {
#IsString()
#IsNotEmpty()
#ApiModelProperty({ required: true, description: 'iCentra id for the patient' })
patientId: string;
#IsString()
#IsNotEmpty()
#ApiModelProperty({ required: true, description: 'an encounter id for the patient' })
encounterId: string;
}
You're trying to decorate a property with a ParamDecorator, that's why you get this error message.
Can you give some more details on your usecase? That would maybe help someone to give some insights on what you're trying to achieve.
I am following a tutorial which is clearly outdated. But I tried my best to follow up with the migration guide but I am still stuck with this one little error.
import { Injectable } from '#angular/core';
import { AngularFireList, AngularFireObject, AngularFireDatabase } from 'angularfire2/database';
import { ExpenseModel } from './expense-model';
#Injectable()
export class ExplistService {
private basePath = '/UD';
explist: AngularFireList<ExpenseModel[]> = null; // list of objects
exp: AngularFireObject<ExpenseModel> = null;
createExpenseModel(exp: ExpenseModel): void {
this.explist.push(exp)
.catch(error => this.handleError(error));
}
I am getting the error at the line
this.explist.push(exp)
Argument of type 'ExpenseModel' is not assignable to parameter of type
'ExpenseModel[]'. Property 'includes' is missing in type
'ExpenseModel'.
AngularJs 2 with Webpack.
I am not able to connect to NYT Api.
ALL ENDOPOINTS TESTED AND WORKING PROPERLY
AngularJs 2 in production mode:
enableProdMode();
App:
-1 component
-1 Service
All other components working/displaying properly.
No other services on app yet.
Service returns with error: (in console)
error: "Collection 'topstories' not found"
The Service
import { Injectable } from '#angular/core';
import { Http, Headers, URLSearchParams, Response } from '#angular/http';
import 'rxjs/add/operator/toPromise';
import { Observable } from 'rxjs';
#Injectable()
export class NewsService {
private topStoriesUrl: string = `https://api.nytimes.com/svc/topstories/v2/politics.json`;
// private topStoriesUrl: string = `https://newsapi.org/v1/articles`;
// Injecting Http capabilities
constructor( private http: Http ) {}
// for error handling
private handleError(error: any): Promise<any>{
console.error("FromSERVICE:::---:::--> ", error);
return Promise.reject( error.message || error );
}
getNews(): Observable<any> {
let parms: URLSearchParams = new URLSearchParams();
parms.set("api-key", "184db335652341518bea3e4a5db85494");
// parms.set("source", "associated-press");
// parms.set("apiKey", "e4e2aa62a883464a87547e8de4336f61");
return this.http.get( this.topStoriesUrl, { search: parms } )
.map( (res: Response) => res['articles'] )
.catch( this.handleError );
}
}
The Component
import { Component, OnInit } from '#angular/core';
import { Router } from '#angular/router';
import { Observable } from 'rxjs';
// service for fetcing news from api
import { NewsService } from '../services/news.service';
#Component({
selector: 'main-news',
templateUrl: '../templates/main-news.component.html'
})
export class MainNewsComponent implements OnInit{
private news: Observable<any>;
constructor(
private router: Router,
private newsService: NewsService
) {}
ngOnInit(): void {
this.newsService.getNews().subscribe( {
next: r => this.news = Observable.of<any[]>(["one"]),
error: err => console.error("From COMPONENT--->", err)
} );
}
}
I have tried this call with both Api from different organizations to get
the same error on the URL resource.
I have tried this same call with said URL with a Ruby script (NET/http) and also directly on the browser address bar, to receive a VALID response on these BOTH cases.
NOT SURE WHY IT FAILS WITH ANGULAR.
HELP!!!
From your console error it looks like the url is not found on server.
The error displayed is returned from server its not angularjs specific error.
Notice 404 not found returned.
So check your url and server again.
Turns out I was missing the:
Access-control-allow-origin
header.
Go figure!
Apparently, it is not added automatically by AngularJs 2.
Thanx
There are lots of resources out there already but I haven't been able to find one that works for one reason or another. Take a generic example: I want to get the response from http://swapi.co/api/people, which will be a list of people from Star Wars.
import {Injectable } from '#angular/core';
import {Http, Response} from '#angular/http';
import {Observable} from 'rxjs/Observable';
import 'rxjs/add/operator/map';
#Injectable()
export class OombaDataService {
constructor(private http: Http) {}
private usersUrl = 'http://swapi.co/api/people/';
getData() {
return this.http.get(this.usersUrl)
.map(this.extractData)
}
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
private handleError (error: any) {
// In a real world app, we might use a remote logging infrastructure
// We'd also dig deeper into the error to get a better message
let errMsg = (error.message) ? error.message :
error.status ? `${error.status} - ${error.statusText}` : 'Server error';
console.error(errMsg); // log to console instead
return Observable.throw(errMsg);
}
}
A lot of this should be correct since it's based on Angular's own tutorial on the matter. But for whatever reason, when I call it in my components, it just returns an observable object without the JSON data. What am I missing?
At this method:
private extractData(res: Response) {
let body = res.json();
return body.data || { };
}
At the first line, you parse the result of the API call as JSON into a JavaScript object.
Then you return the property data of that object, if it exists. If it doesn't exist, you return an empty object ({ }).
The thing is that the API at http://swapi.co/api/people/ does not bring a response that contains a data property, which means that the extractData() method is always returning an observable of an empty object ({ }).
Besides that, the getData() really returns an Observable, so to get its value, you must subscribe to it, such as:
#Component({
...
providers: [OombaDataService]
})
export class SomeComponent {
constructor(oombaDataService: OombaDataService) {
oombaDataService.getData().subscribe(
x => {
console.log("VALUE RECEIVED: ",x);
},
x => {
console.log("ERROR: ",x);
},
() => {
console.log("Completed");
}
);
}
}
And, since, as said, that API's response does not have any .data property in it, the extractData() should really be (at least until you figure out what you want):
private extractData(res: Response) {
return res.json();
}
That should get things working. Here's a working plunker.