I tried using CKEditor5 for my project and when I activated insert image and tried using it, It says ReferenceError: server is not defined. Here is the code:
class MyUploadAdapter {
constructor( loader ) {
this.loader = loader;
}
upload() {
server.onUploadProgress( data => {
loader.uploadTotal = data.total;
loader.uploaded = data.uploaded;
} );
return loader.file
.then( file => server.upload( file ) );
}
abort() {
// Reject the promise returned from the upload() method.
server.abortUpload();
}
_initRequest() {
const xhr = this.xhr = new XMLHttpRequest();
xhr.open( 'POST', '{{ route('ck5_store')}}',true );
xhr.setRequestHeader('X-CSRF-TOKEN',$('meta[name="csrf-token"]').attr('content'));
xhr.responseType = 'json';
}
_initListeners( resolve, reject, file ) {
const xhr = this.xhr;
const loader = this.loader;
const genericErrorText = `Couldn't upload file: ${ file.name }.`;
xhr.addEventListener( 'error', () => reject( genericErrorText ) );
xhr.addEventListener( 'abort', () => reject() );
xhr.addEventListener( 'load', () => {
const response = xhr.response;
if ( !response || response.error ) {
return reject( response && response.error ? response.error.message : genericErrorText );
}
resolve( {
default: response.url
} );
} );
if ( xhr.upload ) {
xhr.upload.addEventListener( 'progress', evt => {
if ( evt.lengthComputable ) {
loader.uploadTotal = evt.total;
loader.uploaded = evt.loaded;
}
} );
}
}
_sendRequest( file ) {
const data = new FormData();
data.append( 'upload', file );
this.xhr.send( data );
}
}
function SimpleUploadAdapterPlugin( editor ) {
editor.plugins.get( 'FileRepository' ).createUploadAdapter = ( loader ) => {
return new MyUploadAdapter( loader );
};
}
ClassicEditor
.create( document.querySelector( '#tab-content-{{$MODULE}} form#{{$MODULE}}_form textarea[id=form_{{$MODULE}}_details]') ,
{
extraPlugins: [ SimpleUploadAdapterPlugin ],
})
.then( editor => {
console.log( editor );
} )
.catch( error => {
console.error( error );
} );
Any idea on what is the problem? Already tried looking for solutions but cannot find anywhere else. Thank you in advance.
I was having the same issue. My solution:
// Starts the upload process.
upload() {
return this.loader.file
.then( file => new Promise( ( resolve, reject ) => {
this._initRequest();
this._initListeners( resolve, reject, file );
this._sendRequest( file );
} ) );
}
// Aborts the upload process.
abort() {
if ( this.xhr ) {
this.xhr.abort();
}
}
I found this solution following documentation.
Related
I think this warning appear when i work with localStorage, some answers in another page is use useEffect(), but I don't know how to use query or mutation in useEffect().How can I fix it?
export const productListForBill = () : GetProductForBill[] =>{
const returnEmtpyArray : GetProductForBill[] = []
if(typeof window !== "undefined"){
if(localStorage.getItem("products"))
{
const tempProduct = JSON.parse(localStorage.getItem("products") || "")
if(Array.isArray(tempProduct)){
return tempProduct
}
}
}
return returnEmtpyArray
}
const Cart = () => {
const { data } = useGetSomeProductQuery({
variables: { productList: productListForBill() },
});
return (
<>
<Navbar />
{data?.getSomeProduct ? (
data.getSomeProduct.map((product) => (
<div key={`${product.name}-${product.type}`}>
name: {product.name} --|-- type: {product.type} --|-- amount :{" "}
{product.amount} --|-- unitPrice : {product.unitPrice} --|-- total:{" "}
{product.totalPrice}
</div>
))
) : (
<div>Nothing in here</div>
)}
</>
);
};
export const getStaticProps: GetStaticProps = async () => {
const apolloClient = initializeApollo();
await apolloClient.query({
query: GetSomeProductDocument,
variables: { productList: productListForBill() },
});
return addApolloState(apolloClient, {
props: {},
});
};
I have to type something for text checker of Stackoverflow, have a nice day!
code of useGetSomeProductQuery, i'm working with graphql and use codegen to generate it at client
#Query((_return) => [ProductOfBill], { nullable: true })
async getSomeProduct(
#Arg("productList", (_type) => [GetProductForBill])
productList: GetProductForBill[]
): Promise<ProductOfBill[] | null | undefined> {
try {
const newList : ProductOfBill[] = await Promise.all(productList.map(async (product) => {
const price = await Price.findOne({
where: {
type: product.type,
product: product.productId,
}
});
const newProductOfBill = ProductOfBill.create({
name:product.name,
amount:product.amount,
type:product.type,
unitPrice:price?.price
})
return newProductOfBill
}))
.then(list => {
console.log(list)
return list
})
.catch(_ => {
const resultList : ProductOfBill[] = []
return resultList
})
return newList;
} catch (error) {
console.log(error);
return undefined;
}
}
Here's my code first
const [getData, setGetData] = useState();
const [ref, setRef] = useState();
const initializeData = async() => {
const userToken = await AsyncStorage.getItem('user_id');
setGetData(JSON.parse(userToken));
}
useEffect(() => {
return initializeData();
},[])
useEffect(() => {
let interval;
if(getData != null)
{
interval = setInterval(() => {
setRef(firestore().collection('**********').where("SendersNo", "==", getData.number));
}, 2000);
}
return () => clearInterval(interval);
},[getData])
useEffect(() => {
if(ref != null)
{
return ref.onSnapshot(querySnapshot => {
const list = [];
querySnapshot.forEach(doc => {
const {
id,driverName,driverContactNumber,driverRating,driverPlateNumber,driverTrackingNumber,userPlaceName,
destinationPlaceName,PaymentMethod,Fare
} = doc.data();
list.push({id: doc.id,driverName,driverContactNumber,driverRating,
driverPlateNumber,driverTrackingNumber,userPlaceName,destinationPlaceName,PaymentMethod,Fare});
});
setUserBookingData(list);
console.log("HEY!");
});
}
},[])
const CurrentTransaction = () => {
if(ref == null)
{
return (
<View>
<Text>You don't have a Current Transaction</Text>
</View>
)
}
else
{
return userBookingData.map((element) => {
return (
<View key={element.id}>
<View>
<Text>{element.name}</Text>
</View>
</View>
)
});
}
}
So currently right now what I am trying to is if there's a data on my firestore it will update on the screen but before updating it I need to get the data from the setGetData so that I can query it but the problem is that when I refresh the whole simulator/page it doesn't get the data but instead just a blank page . But when i edit and save my code without refreshing the page/simulator it can get the data . Can someone help me what I am doing wrong .
EDIT
if I do this
useEffect(() => {
if(ref != null)
{
return ref.onSnapshot(querySnapshot => {
const list = [];
querySnapshot.forEach(doc => {
const {
id,driverName,driverContactNumber,driverRating,driverPlateNumber,driverTrackingNumber,userPlaceName,
destinationPlaceName,PaymentMethod,Fare
} = doc.data();
list.push({id: doc.id,driverName,driverContactNumber,driverRating,
driverPlateNumber,driverTrackingNumber,userPlaceName,destinationPlaceName,PaymentMethod,Fare});
});
setUserBookingData(list);
console.log("HEY!");
});
}
else
{
return null;
}
},[ref])
it keeps looping the console.log('hey') but it can get the data and display it . but it loops so its bad.
i believe snapshot from firebase realtime database is a listener so its doesn't need setinterval
useEffect(() => {
if(getData != null)
{
const ref = firestore().collection('**********').where("SendersNo", "==", getData.number);
ref.onSnapshot(querySnapshot => {
const list = [];
querySnapshot.forEach(doc => {
const {
id,driverName,driverContactNumber,driverRating,driverPlateNumber,driverTrackingNumber,userPlaceName,
destinationPlaceName,PaymentMethod,Fare
} = doc.data();
list.push({id: doc.id,driverName,driverContactNumber,driverRating,
driverPlateNumber,driverTrackingNumber,userPlaceName,destinationPlaceName,PaymentMethod,Fare});
});
setUserBookingData(list);
console.log("HEY!");
});
}
return () => {
//clear your ref listener here
}
},[getData])
if you put a return on use effect it will be called after the screen is no longer used.
useEffect(()=>{
//inside this will be called when the screen complete render
const someListener = DeviceEventEmitter('listentosomething',()=>{
//do something
});
return ()=>{
//inside this will be called after the screen no longer be used
//example go to other screen
someListener.remove();
}
},)
I have this code and I want to catch the errors that happens in the query used by usePaginationFragment.
what happens now is when something goes wrong in the backend, the data.queryName returns null, and there is no way to know about the errors.
the question is how can I receive the errors when happend?
function MyPagination(){
return (
<ErrorBoundary>
<Suspense fallback={"loading..."} >
<PaginationLoadable
preloadedQuery={preloadedQuery}
query={graphql`...`}
/>
</Suspense>
</ErrorBoundary>
)
}
function PaginationLoadable(this: never, props: PaginationLoadableProps){
const preloadedData = usePreloadedQuery<any>(props.query, props.preloadedQuery);
const {data} = usePaginationFragment(
props.fragment,
preloadedData
);
console.log(data[ /*queryName*/ ] === null)
}
Thank you
Here is how I did it, it must throw an error in the NetworkLayer function like so:
new Environment({
network: Network.create(
function fetch(operation, variables) {
return (
Axios
.post(
'*API_NEDPOINT*',
{
query: operation.text,
variables
}
)
.then(
response => {
if(response.data.errors){
const er: any = new Error('ServerError');
er.data = response.data.data;
er.errors = response.data.errors;
return Promise.reject(er);
}
return response.data;
}
)
);
}
),
store
});
Using Angular Rxjs and ngrx
I have an action that dispatch 4 API and I am doing the following =>
#Effect()
getAllModels$ = this.actions$.pipe(
ofType<featureActions.GetAllModelsRequest>(featureActions.ActionTypes.GetAllModelsRequest),
switchMap((action) =>
forkJoin([
this.dataService.GetAllModelFromServer(),
this.dataService.GetAllModelFromHost(),
this.dataService.GetAllModelFromCache(),
this.dataService.GetAllModelFromPreference(),
]).pipe(
map(
([server, host, cache, preference]) =>
new featureActions.GetAllModelsSuccess({
//...
})
),
catchError((error: HttpErrorResponse) => {
return of(new featureActions.GetAllModelsFailed({ error: error.message }));
})
)
)
);
The problem is, when one of those API fail, everything fail and I am in fail action. all the data that got retrieved (before the one endpoint that failed) is lost.
Is there a way to get the data retrieved in the catchError or the only solution is to chain the api one after the other ?
You can write your own implementation of forkJoin. Here is a simple example sourced from the original (https://github.com/ReactiveX/rxjs/blob/master/src/internal/observable/forkJoin.ts):
export function forkJoin2(...args: any[]): Observable<any> {
const resultSelector = popResultSelector(args);
const { args: sources, keys } = argsArgArrayOrObject(args);
if (resultSelector) {
// deprecated path.
return forkJoinInternal(sources, keys).pipe(map((values: any[]) => resultSelector!(...values)));
}
return forkJoinInternal(sources, keys);
}
function forkJoinInternal(sources: ObservableInput<any>[], keys: string[] | null): Observable<any> {
return new Observable((subscriber) => {
const len = sources.length;
if (len === 0) {
subscriber.complete();
return;
}
const values = new Array(len);
let completed = 0;
let emitted = 0;
for (let sourceIndex = 0; sourceIndex < len; sourceIndex++) {
const source = innerFrom(sources[sourceIndex]);
let hasValue = false;
subscriber.add(
source.subscribe({
next: (value) => {
if (!hasValue) {
hasValue = true;
emitted++;
}
values[sourceIndex] = value;
},
error: (err) => { return subscriber.error({ error: err, values }) },
complete: () => {
completed++;
if (completed === len || !hasValue) {
if (emitted === len) {
subscriber.next(keys ? keys.reduce((result, key, i) => (((result as any)[key] = values[i]), result), {}) : values);
}
subscriber.complete();
}
},
})
);
}
});
}
Notice, when an error occurs, you are returning the error along with the values:
error: (err) => { return subscriber.error({ error: err, values }) }
I went with this solution found here : https://medium.com/better-programming/rxjs-error-handling-with-forkjoin-3d4027df70fc
#Effect()
getAllModels$ = this.actions$.pipe(
ofType<featureActions.GetAllModelsRequest>(featureActions.ActionTypes.GetAllModelsRequest),
switchMap((action) =>
forkJoin([
this.dataService.GetAllModelFromServer().pipe(catchError(() => of({ data: [] }))),
this.dataService.GetAllModelFromHost().pipe(catchError(() => of({ data: [] }))),
this.dataService.GetAllModelFromCache().pipe(catchError(() => of({ data: [] }))),
this.dataService.GetAllModelFromPreference().pipe(catchError(() => of({ data: [] }))),
]).pipe(
map(
([server, host, cache, preference]) =>
new featureActions.GetAllModelsSuccess({
//...
})
),
catchError((error: HttpErrorResponse) => {
return of(new featureActions.GetAllModelsFailed({ error: error.message }));
})
)
)
);
I'm trying to use rxjs in conjunction with babeljs to create an async generator function that yields when next is called, throws when error is called, and finishes when complete is called. The problem I have with this is that I can't yield from a callback.
I can await a Promise to handle the return/throw requirement.
async function *getData( observable ) {
await new Promise( ( resolve, reject ) => {
observable.subscribe( {
next( data ) {
yield data; // can't yield here
},
error( err ) {
reject( err );
},
complete() {
resolve();
}
} );
} );
}
( async function example() {
for await( const data of getData( foo ) ) {
console.log( 'data received' );
}
console.log( 'done' );
}() );
Is this possible?
I asked the rubber duck, then I wrote the following code which does what I wanted:
function defer() {
const properties = {},
promise = new Promise( ( resolve, reject ) => {
Object.assign( properties, { resolve, reject } );
} );
return Object.assign( promise, properties );
}
async function *getData( observable ) {
let nextData = defer();
const sub = observable.subscribe( {
next( data ) {
const n = nextData;
nextData = defer();
n.resolve( data );
},
error( err ) {
nextData.reject( err );
},
complete() {
const n = nextData;
nextData = null;
n.resolve();
}
} );
try {
for(;;) {
const value = await nextData;
if( !nextData ) break;
yield value;
}
} finally {
sub.unsubscribe();
}
}
I think a problem with this solution is that the observable could generate several values in one batch (without deferring). This is my proposal:
const defer = () => new Promise (resolve =>
setTimeout (resolve, 0));
async function* getData (observable)
{
let values = [];
let error = null;
let done = false;
observable.subscribe (
data => values.push (data),
err => error = err,
() => done = true);
for (;;)
{
if (values.length)
{
for (const value of values)
yield value;
values = [];
}
if (error)
throw error;
if (done)
return;
await defer ();
}
}