How to display a svelte console in my page - console

I want to add a console panel to my html page like in the REPL page of the svelte site.
https://svelte.dev/repl/hello-world?version=3.55.1
My site was generating as a static site and copy in an ESP8266 micro controller.
I have no idea how to do that :-(

The REPL overwrites the methods of the console object to extend them.
E.g. for the methods that write messages:
['clear', 'log', 'info', 'dir', 'warn', 'error', 'table'].forEach((level) => {
const original = console[level];
console[level] = (...args) => {
const stringifiedArgs = stringify(args);
if (previous.level === level && previous.args && previous.args === stringifiedArgs) {
parent.postMessage({ action: 'console', level, duplicate: true }, '*');
} else {
previous = { level, args: stringifiedArgs };
try {
parent.postMessage({ action: 'console', level, args }, '*');
} catch (err) {
parent.postMessage({ action: 'console', level: 'unclonable' }, '*');
}
}
original(...args);
};
});
Source
This uses postMessage to send a message event containing the logged contents, but you could use other mechanisms as well.

Related

With Strapi 4 how can I get each users music events

I'm using strapi 4 with nextjs.
In the app strapi holds music events for each user and each user should be able add and retrieve there own music events.
I am having trouble retrieving
each users music events from strapi 4
I have a custom route and custom controller
The custom route is in a file called custom-event.js and works ok it is as follows:
module.exports = {
routes: [
{
method: 'GET',
path: '/events/me',
handler: 'custom-controller.me',
config: {
me: {
auth: true,
policies: [],
middlewares: [],
}
}
},
],
}
The controller id a file called custom-controller.js and is as follows:
module.exports = createCoreController(modelUid, ({strapi }) => ({
async me(ctx) {
try {
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{messages: [{ id: 'No authorization header was found'}]}
])
}
// The line below works ok
console.log('user', user);
// The problem seems to be the line below
const data = await strapi.services.events.find({ user: user.id})
// This line does not show at all
console.log('data', data);
if (!data) {
return ctx.notFound()
}
return sanitizeEntity(data, { model: strapi.models.events })
} catch(err) {
ctx.body = err
}
}
}))
Note there are two console.logs the first console.log works it outputs the user info
The second console.log outputs the data it does not show at all. The result I get back
using insomnia is a 200 status and an empty object {}
The following line in the custom-controller.js seems to be where the problem lies it works for strapi 3 but does not seem to work for strapi 4
const data = await strapi.services.events.find({ user: user.id})
After struggling for long time, days infact, I eventually got it working. Below is the code I came up with. I found I needed two queries to the database, because I could not get the events to populate the images with one query. So I got the event ids and then used the event ids in a events query to get the events and images.
Heres the code below:
const utils = require('#strapi/utils')
const { sanitize } = utils
const { createCoreController } = require("#strapi/strapi").factories;
const modelUid = "api::event.event"
module.exports = createCoreController(modelUid, ({strapi }) => ({
async me(ctx) {
try {
const user = ctx.state.user;
if (!user) {
return ctx.badRequest(null, [
{messages: [{ id: 'No authorization header was found'}]}
])
}
// Get event ids
const events = await strapi
.db
.query('plugin::users-permissions.user')
.findMany({
where: {
id: user.id
},
populate: {
events: { select: 'id'}
}
})
if (!events) {
return ctx.notFound()
}
// Get the events into a format for the query
const newEvents = events[0].events.map(evt => ({ id: { $eq: evt.id}}))
// use the newly formatted newEvents in a query to get the users
// events and images
const eventsAndMedia = await strapi.db.query(modelUid).findMany({
where: {
$or: newEvents
},
populate: {image: true}
})
return sanitize.contentAPI.output(eventsAndMedia,
strapi.getModel(modelUid))
} catch(err) {
return ctx.internalServerError(err.message)
}
}
}))

RXJS Subscribe to a Subject - Actions must be plain objects. Use custom middleware for async actions

I'm trying to subscribe to a subject. This is working as expected the first time but throwing the above error the second time and I can't see where to fix it.
export function uploadSceneFile(action$, store) {
return action$.ofType(CREATE_SCENE_SUCCESS)
.mergeMap(({payload}) =>
UploadSceneWithFile(payload)
.map(res => {
if (res.progress > 0){
return { type: UPLOAD_SCENE_PROGRESS, scene: res }
}
else if(res.progress === -1){
return { type: UPLOAD_SCENE_SUCCESS, scene: res }
}
})
)
}
It's designed to listen for the scen being created, dispatch upload progress notifications and then dispatch the success message.
The error gets thrown straight away from this line the second time it runs
onProgress: (val)=> subject$.next({...scene,progress:val}),
export function UploadSceneWithFile(scene){
const subject$ = new Subject()
scene.filename = scene.file.name
scene.type = scene.file.type.match('image') ? 0 : 1
FileToScenePreview(scene).then(res => {
scene.thumbName = res.thumbName
})
const uploader = new S3Upload({
getSignedUrl: getSignedUrl,
uploadRequestHeaders: {'x-amz-acl': 'public-read'},
contentType: scene.file.type,
contentDisposition: 'auto',
s3path: 'assets/',
onError:()=>subject$.next('error'),
onProgress: (val)=> subject$.next({...scene,progress:val}),
onFinishS3Put: ()=> {
subject$.next({...scene,progress:-1})
subject$.complete()
},
})
uploader.uploadFile(scene.file)
return subject$.asObservable()
}
ERROR MESSAGE
Subscriber.js:242 Uncaught Error: Actions must be plain objects. Use custom middleware for async actions.
at Object.performAction (<anonymous>:1:40841)
at liftAction (<anonymous>:1:34377)
at dispatch (<anonymous>:1:38408)
at createEpicMiddleware.js:59
at createEpicMiddleware.js:59
at SafeSubscriber.dispatch [as _next] (applyMiddleware.js:35)
at SafeSubscriber../node_modules/rxjs/Subscriber.js.SafeSubscriber.__tryOrUnsub (Subscriber.js:238)
at SafeSubscriber../node_modules/rxjs/Subscriber.js.SafeSubscriber.next (Subscriber.js:185)
at Subscriber../node_modules/rxjs/Subscriber.js.Subscriber._next (Subscriber.js:125)
at Subscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at SwitchMapSubscriber../node_modules/rxjs/operators/switchMap.js.SwitchMapSubscriber.notifyNext (switchMap.js:126)
at InnerSubscriber../node_modules/rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
at InnerSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at MergeMapSubscriber../node_modules/rxjs/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:145)
at InnerSubscriber../node_modules/rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
at InnerSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at MergeMapSubscriber../node_modules/rxjs/operators/mergeMap.js.MergeMapSubscriber.notifyNext (mergeMap.js:145)
at InnerSubscriber../node_modules/rxjs/InnerSubscriber.js.InnerSubscriber._next (InnerSubscriber.js:23)
at InnerSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at MapSubscriber../node_modules/rxjs/operators/map.js.MapSubscriber._next (map.js:85)
at MapSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at Subject../node_modules/rxjs/Subject.js.Subject.next (Subject.js:55)
at S3Upload.onProgress (uploadSceneFile.js:27)
at S3Upload.<anonymous> (s3upload.js:139)
In the inner map within your uploadSceneFile, you have an if statement followed by an else if statement, of if neither is true, the map will return undefined instead of an action.
.map(res => {
if (res.progress > 0){
return { type: UPLOAD_SCENE_PROGRESS, scene: res }
}
else if(res.progress === -1){
return { type: UPLOAD_SCENE_SUCCESS, scene: res }
}
// An action should be returned here!
})
Note that, when passed an undefined action, the check that Redux performs to determine whether or not an action is a plain object will effect the error you are seeing.

Angular2 - http call Code coverage

My components.ts is,
getHomePageData() : void{
this.homeservice.getHomePageData()
.subscribe(
data => {
//console.log("response status ################### "+data.status);
//console.log("getUserData response ************ \n"+JSON.stringify(data));
this.defaultFacilityId = data.response.defaultFacilityId;
this.defaultFacilityName = data.response.defaultFacilityName;
this.enterpriseId = data.response.enterpriseId;
this.enterpriseName = data.response.enterpriseName;
this.facilityList = data.response.facilityList;
this.userName = data.response.userName;
this.showDefaultPopoup();
},
error => {
console.error(error);
//this.errorMessage="Technical error - Contact Support team !" ;
}
);
}
So my component.spec.ts is ,
it('getHomePageData with SUCCESS - getHomePageData()', () => {
backend.connections.subscribe((connection: MockConnection) => {
//expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
let options = new ResponseOptions({
body:
{
"request": { "url": "/getUserData" },
"response": {
"defaultFacilityName":"3M Health Information Systems",
"enterpriseId":"11.0",
"enterpriseName":"HSA Enterprise",
"defaultFacilityId": "55303.0",
"userName":"Anand"
},
"error": ""
},
status : 200
});
connection.mockRespond(new Response(options));
});
backend.connections.subscribe((data) => {
//expect(data.response.facilityId).toEqual("55303.0");
//expect(subject.handleError).toHaveBeenCalled();
})
service.getHomePageData().subscribe((data) => {
//expect(videos.length).toBe(4);
expect(data.response.defaultFacilityId).toEqual("55303.0");
component.defaultFacilityId = data.response.defaultFacilityId;
component.defaultFacilityName = data.response.defaultFacilityName;
component.enterpriseId = data.response.enterpriseId;
component.enterpriseName = data.response.enterpriseName;
component.userName = data.response.userName;
console.log("$$$$$$$$$$$$$$$$**********$$$$$$$$$$$$$$$$$$$$$");
});
});
When i try to run test case. It got passed. But while I look into the code coverage, it doesn't cover the code shown in red below
Please help to get the full code coverage. Thanks.
In the test you've shown here you don't seem to be calling getHomePageData() from your component
Try building your test like this:
import { fakeAsync, tick } from '#angular/core/testing';
...
it('getHomePageData with SUCCESS - getHomePageData()', fakeAsync(() => {
backend.connections.subscribe((connection: MockConnection) => {
//expect(connection.request.url).toEqual('http://localhost:8080/MSMTestWebApp/UDM/UdmService/Home/');
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
let options = new ResponseOptions({
body:
{
"request": { "url": "/getUserData" },
"response": {
"defaultFacilityName":"3M Health Information Systems",
"enterpriseId":"11.0",
"enterpriseName":"HSA Enterprise",
"defaultFacilityId": "55303.0",
"userName":"Anand"
},
"error": ""
},
status : 200
});
connection.mockRespond(new Response(options));
});
// If this function is not automatically called in the component initialisation
component.getHomePageData();
tick();
//you can call expects on your component's properties now
expect(component.defaultFacilityId).toEqual("55303.0");
});
FakeAsync allows you to write tests in a more linear style so you no longer have to subscribe to the service function to write your expectations.
In a FakeAsync test function you can call tick() after a call where an asynchronous operation takes place to simulate a passage of time and then continue with the flow of your code.
You can read more about this here: https://angular.io/docs/ts/latest/testing/#!#fake-async
EDIT - Error Case
To test the error logic you can call mockError or set up an error response using mockRespond on your connection:
it('getHomePageData with ERROR- getHomePageData()', fakeAsync(() => {
backend.connections.subscribe((connection: MockConnection) => {
if (connection.request.url === 'http://192.168.61.158:9080/GetUserData') {
// mockError option
connection.mockError(new Error('Some error'));
// mockRespond option
connection.mockRespond(new Response(new ResponseOptions({
status: 404,
statusText: 'URL not Found',
})));
}
component.getHomePageData();
tick();
//you can call expects now
expect(connection.request.url).toEqual('http://192.168.61.158:9080/GetUserData');
expect(connection.request.method).toEqual(RequestMethod.Get);
expect(connection.request.headers.get('Content-Type')).toEqual('application/json');
expect('you can test your error logic here');
});
What we're doing inside the subscription is making sure that anytime the GetUserData endpoint is called within this test method it will return an error.
Because we test errors and successes separately in the success test there's no need to add the error related settings in the request options.
Are you using JSON data? Then you should probably use map() before using .subscribe().
.map((res:Response) => res.json())
Try organizing your code like this:
ngOnInit() {
this.getHomePageData();
}
getHomePageData() {
this.http.get('your.json')
.map((res:Response) => res.json())
.subscribe(
data => {
this.YourData = data
},
err => console.error(err),
() => console.log('ok')
);
}
Hope it helps,
Cheers

http into a service with Angular2 with es5

I am working with Angular2 and es5. I want to use http in a service.
Unfortunately I have 2 errors:
- http is undefined, but ng.http.Http is defined,
- I have this error for the main component:
vendor-client.min.js:28 EXCEPTION: Can't resolve all parameters for class0: (t, ?)
Here is my service code:
;(function(app, ng) {
console.log(new ng.http.Http());
app.ApplicationsService = ng.core.Injectable().Class({
constructor: [ng.http.Http, function(http) {
console.log(http);
this.applicationsEmailUrl = 'api/applications/email';
this.http = http;
}],
emailExists: function(email) {
console.log(email);
var data = { email: email };
return this.http.post(this.applicationsEmailUrl, data)
.toPromise()
.then(function(response) { response.json().data; })
.catch(this.handleError);
}
});
})(window.app || (window.app = {}), window.ng);
Here is the main component:
;(function(app, ng) {
app.AppComponent = ng.core
.Component({
selector: 'register-form',
templateUrl: 'src/register/app.component.html'
})
.Class({
constructor: [ng.core.ElementRef, app.ApplicationsService, function(ref, Applications) {
console.log('app.component.js');
this.programs = JSON.parse(ref.nativeElement.getAttribute('programs'));
this.applications = Applications;
}],
emailExists: function(email) {
console.log('emailExists() triggered');
Applications.emailExists(email);
}
});
})(window.app || (window.app = {}), window.ng);
The bootstrap:
;(function(app, ng) {
document.addEventListener('DOMContentLoaded', function() {
ng.platformBrowserDynamic.bootstrap(app.AppComponent, [
ng.forms.disableDeprecatedForms(),
ng.forms.provideForms(),
ng.http.HTTP_PROVIDERS,
app.ApplicationsService
]);
});
})(window.app || (window.app = {}), window.ng);
If I try to inject http into the main component within the providers array, it works. But I would rather prefer to have a service.
I found out the problem. Looks like Angular2 needs to load your code in order. The main component was loaded before the service, so it was undefined. I put all my code in one file and it works. I will use a require loader asap.

In Meteor when trying to access an attribute, I get TypeError: Cannot read property in the console. But the site is working

When trying to read an attribute, meteor gives me a TypeError: Cannot read property 'featuredImage' of undefined error in the browser console. But it reads featuredImage and the site is working fine. How can I get rid of this error? Is it happening because my subscriptions are not yet ready? Is that's the case, how to fix it? (PS : Im using the flow router so I can't wait for subscriptions in the router)
My template code :
Template.About.helpers({
page: () => {
return findPage();
},
featuredImage: () => {
var thisPage = findPage();
return Images.findOne({
"_id": thisPage.featuredImage
});
}
});
function findPage() {
return Pages.findOne({
slug: 'about'
});
}
The router code :
FlowRouter.route('/about', {
name: 'about',
subscriptions: function() {
this.register('page', Meteor.subscribe('pages', 'about'));
this.register('image', Meteor.subscribe('images'));
},
action() {
BlazeLayout.render('MainLayout', {
content: 'About'
});
setTitle('About Us');
},
fastRender: true
});
The subscription is probably not ready yet. FlowRouter provides a utility for dealing with this, your helpers should look like this:
Template.About.helpers({
page: () => {
// If you only need a specific subscription to be ready
return FlowRouter.subsReady('page') && findPage() || null;
},
featuredImage: () => {
// Ensure ALL subscriptions are ready
if ( FlowRouter.subsReady() ) {
var thisPage = findPage();
return Images.findOne({
"_id": thisPage.featuredImage // Probably should be thisPage.featuredImage._id
});
}
return null;
}
});
However, for maximum performance, you should use if (FlowRouter.subsReady('page') && Flowrouter.subsReady('image')) rather than FlowRouter.subsReady() since if you have other pending subscriptions which are large, it will wait for those even though you don't need them.

Resources