send URL parameters to Express with Angular 2 - express

I'm using this Angular service to get data from Express:
getRestaurants(districtId) : Observable<void[]>{
let params: URLSearchParams = new URLSearchParams();
params.set('id', districtId);
return this.http.get(this.url, { search: params })
.map((res:Response) => res.json())
.catch((error:any) => Observable.throw(error.json().error || 'Server error'));
}
I was using this URL http://localhost:5050/api/district/restaurants?id=8
It works fine if in Express I use req.query But I need to use this new URL http://localhost:5050/api/district/:id/restaurants and use req.params in Express.
My problem is that I can't set the :id parameter using Angular without modifying the URL string and I suppose that there is a better way to do this task. Thanks for your help

What about this:
private url = 'http://localhost:5050/api/district/:id/restaurants';
private _prepareUrl(districtId: number): string {
return this.url.replace(':id', districtId);
}
getRestaurants(districtId) {
// ...
this.http.get(this._prepareUrl(districtId), ...);
// ...
}
You could use the Router's function createUrlTree, but you will have a prepare-function too..
private urlPrefix = 'http://localhost:5050/api';
constructor(private _router: Router) { }
private _prepareUrl(districtId: number): string {
return this.urlPrefix + this._router.createUrlTree(['district', districtId, 'restaurants']).toString();
}
getRestaurants(districtId) {
// ...
this.http.get(this._prepareUrl(districtId), ...);
// ...
}

Related

How to use graphql dataloader loadMany function properly in nestjs?

I want to use dataloader loadMany function in nestjs. Can any help me to use it properly-
dataloader.service.ts-
#Injectable()
export class DataloaderService {
constructor(private readonly categoryService: CategoryService) { }
createLoaders(): IDataloaders {
const subCategoryLoader = new DataLoader<ObjectId, Subcategory>(
async (keys: readonly ObjectId[]) =>
this.categoryService.findSubCategoryByBatch(keys as ObjectId[])
);
return {
subCategoryLoader
};
}
}
Then I category service(findSubCategoryByBatch)-
async findSubCategoryByBatch(Ids: ObjectId[]): Promise<(Subcategory | Error)[]> {
const categories = await this.subCategoryModel.find({ _id: { $in: Ids } });
const mappedResults = Ids.map(
(id) =>
categories.find((result) => result.id === id) ||
new Error(`Could not load owner ${id}`),
);
return mappedResults;
}
Then I call it -
#ResolveField('subCategory', () => [Subcategory])
getSubCategory(
#Parent() category: Category,
#Context() { loaders }: IGraphQLContext
) {
return loaders.subCategoryLoader.loadMany(category.subCategory)
}
Notice: I use loadMany function because subCategory is a array IDs.
But I am getting error. Here How to write function for loadMany function. Please help me. I need it. Please help me. please help me.

Shopify Storage Redis Issue with Node React App

I have added session storage in serve.js as follows :-
import SessionHandler from "./SessionHandler";
const sessionStorage = new SessionHandler();
Shopify.Context.initialize({
API_KEY: process.env.SHOPIFY_API_KEY,
API_SECRET_KEY: process.env.SHOPIFY_API_SECRET,
SCOPES: process.env.SCOPES.split(","),
HOST_NAME: process.env.HOST.replace(/https:\/\//, ""),
API_VERSION: ApiVersion.October21,
IS_EMBEDDED_APP: false,
// This should be replaced with your preferred storage strategy
//SESSION_STORAGE: new Shopify.Session.MemorySessionStorage(),
SESSION_STORAGE: new Shopify.Session.CustomSessionStorage(
sessionStorage.storeCallback,
sessionStorage.loadCallback,
sessionStorage.deleteCallback
),
});
My router get function is
router.get("(.*)", async (ctx) => {
const shop = ctx.query.shop;
let documentQuery = { shop: shop };
let data = await SessionStorage.findOne(documentQuery); //this finds the store in the session table
if (ACTIVE_SHOPIFY_SHOPS[shop] === undefined) {
if (data == null) {
ctx.redirect(`/auth?shop=${shop}`);
} else {
await handleRequest(ctx);
}
} else {
await handleRequest(ctx);
}
});
and than in the SessionHandler file added code as attached in file ,
but when I run install the app it goes to the storeCallback , loadcallback and deletecallback function multiple times
StoreCallback Function Code
Load and delete callback function code
sorry I have edited my answer as I think its incorrect . all I can say for now is to look at this example:https://github.com/Shopify/shopify-api-node/blob/main/docs/usage/customsessions.md
if you havent already..

Infinite loop with a graphql and mongoose backend

I have a backend made in express and mongoose:
all my mutations and queries work perfectly except one mutation sends me an infinite loader
updateVehicleVerification: async (_, { id, updateVehicleVerification }) => {
const vehicleVeri = await VehicleVerification.findById(id);
if (!vehicleVeri) {
throw new Error(ErrorMessage + ' : Verification de Vehicule');
}
await VehicleVerification.findByIdAndUpdate(
id,
updateVehicleVerification
);
const veri = await VehicleVerification.findById(id);
return veri;
},
and the query I use here:
export const UPDATE_CONTROL_VEHICLE = gqlmutation updateVehicleVerification( $id: String! $updateVehicleVerification: VerificationVehicleInput ) { updateVehicleVerification( id: $id updateVehicleVerification: $updateVehicleVerification ) { honk { state image comment } mileage dateVerification stateVehicle { damaged good missing } } };
enter code here
I I solved the problem !
I did not manage the case where the data reached me by the request which keyed an infinite loop.

How to send Http Form with parameters by ktor-client

I've found nearly everywhere in ktor-client documentation and examples they use empty formData to show how the client works
formParameters: Parameters = Parameters.Empty
So what's the kotlin/ktor way to fill it with parameters?
Ktor uses this approach to fill the parameters:
client.submitForm<HttpResponse>(
url = "https://foo.com/login",
formParameters = Parameters.build {
append("_username", username)
append("_password", password)
})
Alternatively, you can also simply pass the form data using formData, e.g.:
client.post<HttpResponse>("https://example.com/login") {
formData {
parameter("username", username)
parameter("password", password)
}
}
I've found at least three ways to post www-urlencoded form:
return httpClient.submitForm("url") {
parameter("key", "value")
}
return httpClient.post("url") {
FormDataContent(Parameters.build {
parameter("key", "value")
})
}
return httpClient.post("url") {
formData {
parameter("key", "value")
}
}
append() method is marked as internal and not working with ktor 1.6.4
client.get{
url("https://api.yelp.com/v3/businesses/search")
contentType(ContentType.Application.Json)
headers {
append(HttpHeaders.Authorization, "Bearer $API_KEY")
}
formData {
parameter("location","NYC") //use this wey
}
}

Angular 5 HTTPClient not returning results for RouteResolver

I have to say HttpClient Observables, subscriptions etc are pretty hard/time consuming to get right.
I have been working on a problem for a while now and tearing my hair out. I have a service that I need to be able to perform a mapping function on.
loadAllSummary(organisationId: number) {
return this.http.get('/api/aircrafts/organisations/' + organisationId)
.pipe(
map(data => data.forEach(datum => {
console.log('why am i not getting here! ' + JSON.stringify(data));
return this.mapToSummary(datum);
}))
);
}
with the mapToSummary() method:
private mapToSummary(aircraft: Aircraft): IAircraftSummary {
const lastDate: Date = new Date(Math.max.apply(null, aircraft.workorders.map(function(e) {
return new Date(e.date);
})));
return new AircraftSummary({
lastWork: lastDate,
rego: aircraft.registration,
make: aircraft.make,
model: aircraft.model,
contact: (aircraft.owner.type.endsWith('primary')) ? aircraft.owner.principal : aircraft.operator.principal,
phone: (aircraft.owner.type.endsWith('primary')) ? aircraft.owner.contact.phone : aircraft.operator.contact.phone
});
}
Now, I need these summaries as input data to a view, so I borrowed code from the interwebs and created this ResolverService:
#Injectable()
export class AircraftsResolverService implements Resolve<IAircraftSummary[]> {
constructor(private service: AircraftService,
private router: Router) { }
resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<IAircraftSummary[]> {
console.log('called AircraftsResolverService')
const id = route.params['id'];
if (isNaN(+id)) {
console.log(`Organisation id was not a number: ${id}`);
this.router.navigate(['/login']);
return Observable.of(null);
}
return this.service.loadAllSummary(+id)
.map(summaries => {
console.log(summaries)
if (summaries) {
return summaries;
}
console.log(`Summaries were not found: ${id}`);
this.router.navigate(['/organisations/', +id]);
return null;
})
.catch(error => {
console.log(`Retrieval error: ${error}`);
this.router.navigate(['/organisations/', +id]);
return Observable.of(null);
});
}
}
Which I then refer to in the ngOnInit call...
ngOnInit() {
this.currentUser = this.authenticationService.returnCurrentUser();
this.route.data
.subscribe(({aircrafts}) => {
this.aircrafts = aircrafts;
const id = +this.route.snapshot.paramMap.get('id');
console.log(' where are my aircraft!' + JSON.stringify(aircrafts));
this.ELEMENT_DATA = aircrafts;
this.displayedColumns = ['Last Work', 'Rego', 'Make', 'Model', 'Contact', 'Phone'];
this.dataSource = new MatTableDataSource(this.ELEMENT_DATA);
this.dataSource.sort = this.sort;
console.log(id);
if (id) {
this.organisationService.getById(id).subscribe(org => {
this.organisation = org;
});
} else {
console.log('its bad');
}
});
console.log(this.dataSource);
}
The console log under the subscribe is undefined and the console.logs under the service never get triggered. So once again, I find myself not understanding why subscription fire or not fire, or whatever it is that they do.
How do I get past this? thanks everyone.
EDIT: appears that the problem is actually in the ResolverService, I have been able to determine that the data service is getting the results and that they are correct. For some reason, the resolver service can't see them.
The answer was in the route resolver, or rather the app-routing-module. I should have included it in the question, because some of the angular saltys would have picked it up
I was trying to do this:.
{ path: 'organisations/:orgId/aircrafts/:id', component: AircraftsComponent, resolve: {aircrafts : AircraftsResolverService}, canActivate: [AuthGuard] },
But you can't, you have to do this:
{ path: 'organisations/aircrafts/:orgId/:id', component: AircraftsComponent, resolve: {aircrafts : AircraftsResolverService}, canActivate: [AuthGuard] },
results in very non-resty urls, but, hey, whatever works, right?