I have a problem with displaying image on my project. I want in the .subscribe task the download url to equal as image. So it can display it. But when I do that it shows an error message:
Type 'UploadTaskSnapshot' is not assignable to type 'string'.
Here is the code:
export class PostDashboardComponent implements OnInit {
title: string;
image: string = null;
content: string;
buttonText: string = "Create Post";
uploadPercent: Observable<number>;
downloadURL: Observable<string>;
constructor(
private auth: AuthService,
private postService: PostService,
private storage: AngularFireStorage
) { }
ngOnInit() {
}
uploadImage(event) {
const file = event.target.files[0]
const path = `posts/${file.name}`
const fileRef = this.storage.ref(path);
if (file.type.split('/')[0] !== 'image') {
return alert('only image files')
} else {
const task = this.storage.upload(path, file)
this.uploadPercent = task.percentageChanges();
task.snapshotChanges().pipe(
finalize(() => this.downloadURL = fileRef.getDownloadURL() )
)
.subscribe(url => (this.image = url))
console.log('Image Uploaded!');
What should I change to make it work because I am an amateur. Thank you for your help.
I found the answer and is this:
uploadImage(event) {
const file = event.target.files[0]
const path = `posts/${file.name}`
const fileRef = this.storage.ref(path);
if (file.type.split('/')[0] !== 'image') {
return alert('only image files')
} else {
const task = this.storage.upload(path, file);
const ref = this.storage.ref(path);
this.uploadPercent = task.percentageChanges();
console.log('Image uploaded!');
task.snapshotChanges().pipe(
finalize(() => {
this.downloadURL = ref.getDownloadURL()
this.downloadURL.subscribe(url => (this.image = url));
})
)
.subscribe();
Related
With a few versions of IOS, The context object is undefined and when checked in the network tab the cached .json files in the browser disk cache throw "403" error on the click of back button.
Attached is the snapshot of the network tab. Works fine perfectly in the chrome browser.
This is the live site https://www.directv.com/forbusiness/ and it's accessible outside US there is no geofencing.
The context is undefined i.e ctx && ctx.req.cache, Snippet from one of the page
customerServiceIndex.getInitialProps = async (ctx) => {
const page: string =
ctx && ctx.query && ctx.query.page.length > 0
? ctx.query.page
: `customer-support`;
const path: string = `/dtvcms/dtvb/prod/customerservice.model.dtv.json`;
let pages = ctx?.query?.page;
let reqQueryParams: any;
if (ctx.req) {
reqQueryParams = ctx?.req?.query;
} else {
reqQueryParams = queryStringToObject(window.location.search);
}
let pagesInfoData = await fetchPageData(ctx, ctx.query.page, page, path);
let cmsFeed = pagesInfoData?.cmsFeed;
let feed = pagesInfoData?.feed;
let fragments: any = feed && feed?.data ? feed.data : {};
const contentProvider: ContentProvider = new ContentProvider();
const data = contentProvider.buildDataFromLayout(
// data1,
fragments,
page,
pages,
null,
reqQueryParams,
ctx.asPath
);
const initialProps = {
data,
err: cmsFeed == "" ? { statusCode: 404 } : undefined,
feed: fragments?.pageProperties?.elements?.analyticsPageLoad?.analytics,
cmsFeed: cmsFeed,
page,
pagePath: ctx.asPath,
seo: fragments?.pageProperties?.elements || undefined,
root: publicRuntimeConfig.root,
};
return initialProps;
};
---- Fetch Call ------
export const fetchPageData = async (
ctx,
page: string,
currentPage,
path: String
) => {
console.log("currentPAge", currentPage);
let authorization: string = ``;
let cmsSource: string = ``;
let contentSource: string = ``;
page = ctx.query && ctx.query.page ? ctx.query.page : currentPage;
let cmsVersion: string = ``;
let pages: { [key: string]: { [key: string]: string } };
let ctxuserAgent: string;
let reqQueryParams: any;
let is404page: boolean;
let dbData: any;
let feed: any = {};
if (ctx?.req) {
if (ctx?.query) {
authorization = ctx?.query?.authorization || authorization;
cmsSource = ctx?.query?.contentSourceBu6dot5;
contentSource = ctx?.query?.contentSource || contentSource;
pages = ctx?.query?.pages || {};
}
cmsVersion = ctx?.req?.query ? ctx?.req?.query.cmsversion : cmsVersion;
ctxuserAgent =
ctx?.req?.headers["idpctx-user-agent"] || ctx?.req?.headers["user-agent"];
is404page = ctx?.query && ctx?.query?.is404Page === true;
delete ctx.query.depVersion;
delete ctx.query.authorization;
delete ctx.query.pages;
reqQueryParams = ctx?.req?.query;
} else {
dbData = (await dbGet(page)) as {
[key: string]: { [key: string]: string };
};
if (typeof window !== undefined) {
cmsSource = `${window.location.protocol}//${window.location.host}`;
}
reqQueryParams = queryStringToObject(window?.location?.search);
}
console.log(`DBDB`, dbData);
console.log(`pages`, pages);
const cmsFeed: string =
pages &&
pages[page] &&
pages[page].cmsFeed &&
pages[page].cmsFeed.length > 0
? pages[page].cmsFeed
: dbData && dbData.cmsFeed && dbData.cmsFeed.length > 0
? dbData.cmsFeed
: path;
let cacheData: any =
ctx && ctx?.req && ctx?.req?.cache ? ctx?.req?.cache : {};
feed = await handleResponse(cacheData);
if (cmsSource === "") {
if (process?.env?.GN_6DOT5_CMS_HOST) {
cmsSource = `${process?.env?.GN_6DOT5_CMS_HOST}`
console.log("#### ")
} else {
cmsSource =
publicRuntimeConfig && publicRuntimeConfig.prod === false
? `https://tst3.directv.com`
: `https://www.directv.com`;
}
}
const url = `${cmsSource}${cmsFeed}`;
if (!Object.values(feed).some((v) => v)) {
console.log("cms cache failed going to call api");
feed = await failoverCmsCall(url, page);
}
return {
feed,
pages,
cmsFeed,
};
};
I'm thinking it has to do with the permissions on the
https://www.directtv.com/dtvcms/etc
You don't have the necessary authorisation to view or fetch data from that page. If you own that domain, make sure you're responding with the right authorisation.
I am trying to save the id that I get from the MongoDB while saving the stock information as a property of stock using the following code but I get some errors:
async save(stock : Stock) {
const id = await stockCollection.insertOne(stock);
console.log('this is the id: ', id.toString());
stock.id = id.toString();
console.log(stock.id);
// delete stock._id;
return this;
}
The result of
console.log('this is the id: ', id.toString());
is:
this is the id: 621e826f90e8bf45a3fe493d
And the result of
console.log(stock.id);
Is also the same:
621e826f90e8bf45a3fe493d
But when I check the database I see the saved document like below:
{"_id":{"$oid":"621e7fc2f5b14f28463f289f"},"id":"","open":"2660.7250","high":"2660.7250","low":"2660.5700","close":"2660.5700","volume":"1826"}
It seems the line stock.id = id.toString(); doesn't work and it can not put the id into the id property of the stock.
Also when I try to remove the _id property of the saved stock using this line of the code:
delete stock._id;
It gives me this error:
Property '_id' does not exist on type 'Stock'.deno-ts(2339)
What is the problem and how can I resolve it?
EDIT: stock is an instance of Stock class that loads data of a stock using alpha vantage library.
stock.ts:
import { stockCollection } from "../mongo.ts";
import BaseModel from "./base_model.ts";
export default class Stock extends BaseModel {
public id: string = "";
public open: string = "";
public high: string = "";
public low: string = "";
public close: string = "";
public volume: string = "";
constructor({ id = "", open = "", high = "", low = "" ,close = "", volume = "" }) {
super();
this.id = id;
this.open = open;
this.high = high;
this.low = low;
this.close = close;
this.volume = volume;
}
static async findOne(params: object): Promise<Stock | null> {
const stock = await stockCollection.findOne(params);
if (!stock) {
console.log('there is no stock');
return null;
}
console.log('there is a stock');
return new Stock(Stock.prepare(stock));
}
async save(stock : Stock) {
const id = await stockCollection.insertOne(stock);
console.log('this is the id: ', id.toString());
stock.id = id.toString();
console.log(stock.id);
// delete stock._id;
return this;
}
}
BaseModel.ts:
export default class BaseModel {
public static prepare(data: any) {
data.id = data._id.toString();
// delete data._id;
return data;
}
}
Here I am trying to save one instance of a stock in database:
export const stockSave = async () => {
const YOUR_API_KEY = '***********';
const alpha = new AlaphaVantage('***********');
const writestock = await alpha.stocks.intraday('GOOG' , '1min' ).then((data: any) => {return data["Time Series (1min)"]["2022-02-28 14:31:00"]} );
console.log('this is writestock' , writestock);
const stock = new Stock({
id: "",
open: writestock["1. open"],
high: writestock["2. high"],
low: writestock["3. low"],
close: writestock["4. close"],
volume: writestock["5. volume"]});
await stock.save(stock);
}
Edit2: This is the whole project code: https://github.com/learner00000/back
Because you don't instantiate each instance of Stock with an actual ID, and you are instead relying on the ID to be generated by MongoDB, you should not store the id property in the database. You'll probably need to update your schema to reflect this.
You haven't shown a reproducible example with all of the imports and data, so I'm left to guess a bit about some types, but you can refactor the relevant parts of the class like this:
TS Playground
const stockDataKeys = ['close', 'high', 'low', 'open', 'volume'] as const;
type StockDataKey = typeof stockDataKeys[number];
type StockData = Record<StockDataKey, string>;
class Stock extends BaseModel implements StockData {
public id: string;
public close: string;
public high: string;
public low: string;
public open: string;
public volume: string;
constructor (init: Partial<StockData & { id: string; }> = {}) {
super();
this.id = init.id ?? '';
this.close = init.close ?? '';
this.high = init.high ?? '';
this.low = init.low ?? '';
this.open = init.open ?? '';
this.volume = init.volume ?? '';
}
getData (): StockData {
const data = {} as StockData;
for (const key of stockDataKeys) data[key] = this[key];
return data;
}
hasId (): boolean {
return Boolean(this.id);
}
async save (): Promise<void> {
const data = this.getData();
const id = await stockCollection.insertOne(data);
this.id = id.toString();
}
}
I know that Apollo 2 allowed custom directives by extending the class "SchemaDirectiveVisitor." However, I am using apollo 3 and I know that the way to achieve this now is by using graphql-tools/utils and graphql-tools/schema.
In my index.js I have the following code:
const serverServer = async () => {
app.use(AuthMiddleware);
app.use(
cors({
origin: 'mydomain',
})
);
let schema = makeExecutableSchema({
typeDefs: [typeDefsLibrary, typeDefsDynamicContent, userTypeDefs],
resolvers: {
Query,
Mutation,
Article,
Blog,
Podcast,
SermonNotes,
Sermon,
// dynamic Content
Friday,
Thursday,
// Post Content
Commentary,
Quote,
Thought,
UserContent_SermonNotes,
// User Content
User,
All_Posts,
},
});
schema = AuthorizationDirective(schema, 'auth');
const apolloServer = new ApolloServer({
schema,
context: ({ req }) => {
const { isAuth, user } = req;
return {
req,
isAuth,
user,
};
},
});
await apolloServer.start();
apolloServer.applyMiddleware({ app: app, path: '/api' });
app.listen(process.env.PORT, () => {
console.log(`listening on port 4000`);
});
};
serverServer();
then on my schema file I have:
directive #auth(requires: [RoleName] ) on OBJECT | FIELD_DEFINITION
enum RoleName {
SUPERADMIN
ADMIN
}
type Commentary #auth(requires: [SUPERADMIN, ADMIN]) {
ID: ID
USER_ID: ID
VERSE_ID: String
body: String
category_tags: String
referenced_verses: String
verse_citation: String
created_date: String
posted_on: String
creator(avatarOnly: Boolean): User
comments(showComment: Boolean): [Commentary_Comment]
approvals: [Commentary_Approval]
total_count: Int
}
and this is my custom directive code:
const { mapSchema, getDirective, MapperKind } = require('#graphql-tools/utils');
const { defaultFieldResolver } = require('graphql');
const { ApolloError } = require('apollo-server-express');
//const { logging } = require('../../helpers');
module.exports.AuthorizationDirective = (schema, directiveName) => {
return mapSchema(schema, {
[MapperKind.FIELD]: (fieldConfig, _fieldName, typeName) => {
const authDirective = getDirective(schema, fieldConfig, directiveName);
console.log('auth Directive line 10: ', authDirective);
if (authDirective && authDirective.length) {
const requiredRoles = authDirective[0].requires;
if (requiredRoles && requiredRoles.length) {
const { resolve = defaultFieldResolver } = fieldConfig;
fieldConfig.resolve = function (source, args, context, info) {
if (requiredRoles.includes('PUBLIC')) {
console.log(
`==> ${context.code || 'ANONYMOUS'} ACCESSING PUBLIC RESOLVER: ${
info.fieldName
}`
);
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
}
if (!requiredRoles.includes(context.code)) {
throw new ApolloError('NOT AUTHORIZED', 'NO_AUTH');
}
console.log(`==> ${context.code} ACCESSING PRIVATE RESOLVER: ${info.fieldName}`);
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
};
return fieldConfig;
}
}
},
});
};
But is not working. It seems like it is not even calling the Custom Directive. As you see I have a "console.log('auth Directive line 10: ', authDirective);" on my schema directive function that return "undefined."
I know this post is so ling but I hope someone can help!
Thanks in advance!
Below is the code worked for me
I have used [MapperKind.OBJECT_FIELD]: not [MapperKind.FIELD]:
I have referred this from #graphql-tools ->
https://www.graphql-tools.com/docs/schema-directives#enforcing-access-permissions
`
const { mapSchema, getDirective, MapperKind } = require('#graphql-tools/utils');
const { defaultFieldResolver } = require('graphql');
const HasRoleDirective = (schema, directiveName) => {
return mapSchema(schema, {
// Executes once for each object field in the schems
[MapperKind.OBJECT_FIELD]: (fieldConfig, _fieldName, typeName) => {
// Check whether this field has the specified directive
const authDirective = getDirective(schema, fieldConfig, directiveName);
if (authDirective && authDirective.length) {
const requiredRoles = authDirective[0].requires;
// console.log("requiredRoles: ", requiredRoles);
if (requiredRoles && requiredRoles.length) {
// Get this field's original resolver
const { resolve = defaultFieldResolver } = fieldConfig;
// Replace the original resolver with function that "first" calls
fieldConfig.resolve = function (source, args, context, info) {
// console.log("Context Directive: ", context);
const { currentUser } = context;
if(!currentUser) throw new Error("Not Authenticated");
const { type } = currentUser['userInfo']
const isAuthorized = hasRole(type, requiredRoles);
if(!isAuthorized) throw new Error("You Have Not Enough Permissions!")
//logging(context, info.fieldName, args);
return resolve(source, args, context, info);
};
return fieldConfig;
}
}
}
})
}
`
I was writing code - plugging around with webworkers. It was literally working perfectly - worker running, hit save, and now Next.js considers the file a (video/mp2t)...wat?
I L.I.T.E.R.A.L.L.Y just hit save. No server reboot, config change no nothing. It was working.
Here's the worker if anyone smarter than me can identify some magic phrase or something idk.
I really am stuck here, please help.
/* eslint-disable no-return-assign */
/* eslint-disable no-param-reassign */
/* eslint-disable no-restricted-globals */
import { nanoid } from 'nanoid';
export interface FileObj {
file: File;
path: string;
relativePath?: string;
folder: string;
id: string;
}
type Files = FileObj[];
export const createQueue = (files: Files) => {
const obj: any = {};
const pathIds: any = {};
files.forEach(({ path, ...rest }: { path: string }) => {
const split = path.split('/').filter((f: string) => f);
split.shift();
const relativePath = split.join('/');
if (!pathIds[split[0]]) pathIds[split[0]] = nanoid();
if (!obj[pathIds[split[0]]]) obj[pathIds[split[0]]] = [];
obj[pathIds[split[0]]].push({
path,
folder: split[0],
relativePath,
id: pathIds[split[0]],
...rest,
});
});
return obj;
};
interface Queue {
[key: string]: FileObj[];
}
const parseQueue = (queue: Queue) => Object.entries(queue).map(([key, value]) => {
const files: any[] = [];
const objectType = value.length > 1 ? 'folder' : 'file';
let entityName = '';
let cumulativeSize = 0;
value.forEach((fileObj: FileObj) => {
const {
file: { name, size, type },
relativePath,
folder,
path,
} = fileObj;
files.push({
name,
size,
folder,
type,
relativePath,
path,
});
cumulativeSize += size;
entityName = folder;
});
return {
id: key,
objectType,
cumulativeSize,
files,
entityName,
};
});
function zip(folderObject: { files: Files; id: string }) {
// console.debug('zip files', files);
const zipper = new Worker(
new URL('../workers/zipper.worker.ts', import.meta.url),
);
zipper.onmessage = (evt: any) => {
console.debug('bundler zip', evt.data);
if (evt.data.type === 'result') {
postMessage(evt.data, [evt.data.payload.buffer]);
} else {
postMessage(evt.data);
}
if (evt.data.type === 'result') {
fetch(evt.data.payload).then((b) => console.debug(b.blob()));
zipper.terminate();
fetch(evt.data.payload).then((b) => console.debug(b.blob()));
}
};
zipper.postMessage(folderObject);
}
function gzip(file: FileObj) {
const gzipper = new Worker(
new URL('../workers/gzipper.worker.ts', import.meta.url),
);
gzipper.onmessage = (evt: any) => {
console.debug('bundler gzip', evt.data);
// postMessage(evt.data, [evt.data.payload.buffer]);
gzipper.terminate();
};
gzipper.postMessage(file);
}
function delegate(id: string, files: Files) {
console.debug({ id, files });
if (files.length > 1) {
zip({ files, id });
} else if (files.length === 1) {
gzip({ ...files[0], id });
}
}
addEventListener('message', (event: MessageEvent) => {
console.debug('gay');
const queue = createQueue(event.data);
postMessage({ payload: parseQueue(queue), type: 'queue', source: 'bundler' });
Object.entries(queue).forEach(([id, files]: any) => {
delegate(id, files);
});
});
export {};
I'm creating a permission service using react typescript and I ran into the following problem. I have the class:
import {IPermission} from "../interfaces/IPermission";
class PermissionService {
private permissions: IPermission[] = [];
constructor(permissions: IPermission[]) {
this.permissions = permissions;
}
public getValue(key: string): IPermission['value'] {
const perm = this.permissions.find(permission => permission.key === key);
if (!perm) {
throw new Error('Could not find the permission');
}
return perm.value;
}
public modifyPermission(key: string, defaultValue: any, value: any): void {
const perms = [...this.permissions];
for (let i = 0; i < perms.length; i++) {
perms[i].defaultValue = defaultValue;
perms[i].value = value
}
this.permissions = perms;
console.log(perms);
}
public parseActivePermissions(permissions: IPermission[]): IPermission[] {
this.permissions.forEach(permission => {
permissions.forEach(activePermission => {
if (permission.key === activePermission.key) {
permission.defaultValue = activePermission.defaultValue;
permission.value = activePermission.value;
}
})
})
return this.permissions;
}
public getAll(): IPermission[] {
return this.permissions;
}
}
export default PermissionService;
and an AdminPermissions data file
import PermissionService from "../services/permission.service";
import {IPermission} from "../interfaces/IPermission";
import Permissions from "./Permissions";
const service: PermissionService = new PermissionService(Permissions);
service.modifyPermission('canAccessAcp', true, true);
const AdminPermissions: IPermission[] = service.getAll();
export default AdminPermissions;
The problem is, the service.modifyPermission() does not update the defaultValue and value of the permission. It's still false when console logging. Why is that?
UPDATE #1
Changed the file a bit. Still doesn't work. Now I'm directly changing the values, but they still log as false.
class AdminPermissions {
public getAll(): IPermission[] {
const service: PermissionService = new PermissionService(Permissions);
service.permissions.forEach(permission => {
if (permission.key === 'canAccessAcp') {
permission.defaultValue = true;
permission.value = true;
}
})
return service.permissions;
}
}
The problem is that with forEach you are not changing the actual value of each items, so you should do something like this:
class AdminPermissions {
public getAll(): IPermission[] {
const service: PermissionService = new PermissionService(Permissions);
return service.permissions.map(permission => {
if (permission.key === 'canAccessAcp') {
return (
{
...permission,
defaultValue: true,
value: true
}
)
}
return permission
});
}
}
I found a solution.
In the permission.service.ts
public modifyPermission(key: string, defaultValue: any, value: any): void {
const perms: IPermission[] = this.permissions.map(permission => {
if (permission.key === key) {
console.log('found permission');
return {
...permission,
defaultValue,
value
}
}
return permission
})
this.permissions = perms;
}