websocket not working while adding fuction over join method - websocket

I am new to phoenix programming while I'm learning I'm following Stephen graders udemy course.
While creating a channel to create a comment section, it works finely on first code but when I made a function, the join method is not working properly.
socket.connect();
let channel = socket.channel(`comments:1`, {});
channel
.join()
.receive('ok', resp => {
console.log('Joined successfully', resp);
})
.receive('error', resp => {
console.log('Unable to join', resp);
});
export default socket;
it gives me a joined successfully response in my console.but when I make the function like this...
socket.connect();
const createSocket = topicId => {
let channel = socket.channel(`comments:%{topicId}`, {});
channel
.join()
.receive('ok', resp => {
console.log('Joined successfully', resp);
})
.receive('error', resp => {
console.log('Unable to join', resp);
});
};
window.createSocket = createSocket;
and I called in html file...
<script>
window.createSocket(<%= #topic.id %>)
</script>
while compiling I got an error that websocket disconnected while handshaking....

You probably need to use javascript string interpolation operator
`comments:${topicId}`
instead of
`comments:%{topicId}`
Note the $ instead of %

Related

How to store the response of a request in Cypress?

I have the following code
cy.intercept('GET', Cypress.env('activationCode')).as('getActivationCode')
let validationCode;
cy.request('GET', Cypress.env('activationCode'))
.then( ({ body }) => {
validationCode = body
console.log(body);
// this have the value
})
cy.wait('#getActivationCode')
console.log(validationCode)
// this is undefined
I need to receive a variable from a get request to fill a form but I don't know how to expect it to receive the value so that the execution can continue.
I don't want to code inside the then of the request.
console.log(validationCode) This is coming as undefined because of non-cypress commands are run before the cypress commands. So before validationCode is updated with any value, it is being printed. To avoid this us cy.log(). Also the the way cypress recommends to use variables is by using alias.
cy.intercept('GET', Cypress.env('activationCode')).as('getActivationCode')
cy.request('GET', Cypress.env('activationCode')).then(({body}) => {
cy.wrap(body).as('responseBody') //save response body using alias
console.log(body)
// this have the value
})
cy.wait('#getActivationCode')
cy.get('#responseBody').then((responseBody) => {
cy.log(responseBody) //prints the response body
})
If you want to use console.log you can do this:
let validationCode
cy.request('GET', Cypress.env('activationCode'))
.then(({body}) => {
validationCode = body
console.log(body)
// this have the value
})
.then(() => {
cy.wait('#getActivationCode')
console.log(body)
})
Cypress commands are async, so you should be careful when you mix async and sync code.
You can easily accessa certain property from a request by using the .its() command.
cy.intercept('GET', Cypress.env('activationCode'))
.its('response.body.variableIWant') // you'll need drill down to your specific variable you want
.as('variableIWant')
// some other code
cy.get('#variableIWant')
Another way using .then()
cy.intercept('GET', Cypress.env('activationCode'))
.its('response')
.then( resp = >{
// some code to get variable you want
return variableIWant //this will become new subject for cy commands
})
.as('variableIWant')
// some other code
cy.get('#variableIWant')
Another alternative, use combination before(), function() and .this
before(function() {
cy.request('GET', Cypress.env('activationCode'))
.then( ({ body }) => {
return body
})
.as('validationCode') // puts body into this.validationCode
})
it('tests the validationCode', function() {
console.log(this.validationCode)
})
it('another test of validationCode', function() {
console.log(this.validationCode)
})
You should look at Verifying the request modification
cy.intercept() cannot be debugged using cy.request()! Cypress only intercepts requests made by your front-end application.
Which means the cy.request() will not fire the cy.intercept()

error Policy in Apollo Client React does'nt work

I have aproblem when test Apollo.When I try query with apollo and graphql, i want response return error and partical data, so I set property errorPolicy:'all'. But its not work. I don't no why? Help please!
Here my code:
query { animal {
name
age }, school {
name
numberfd } } `
const { loading,data,error} = useQuery(GET_DASHBOARD_DATA, {
errorPolicy:'all',
onCompleted: (res) => {console.log("complete",res)},
onError : (res,data) => {console.log("ERRRR",res,data)},
})
and i want to receive:
{
error:[...], data:[animal:[...]] }
but its only response error.Here is Apollo's doc: https://www.apollographql.com/docs/react/data/error-handling/
onError type is onError?: (error: ApolloError) => void;. You don't have data inside onError callback.
After useQuery you can add:
console.log('data', data)
console.log('error', error)
I faced the same issue with errorPolicy: 'all', I only received the partial result inside onCompleted callback of useQuery, but no errors.
I created an ErrorLink like this:
private createErrorLink = () => {
return new ApolloLink((operation, forward) => {
return forward(operation).map((response) => {
// filter out errors you don't want to display
const errors = filterSomeErrors(response.errors);
if (errors && response?.data) {
response.data.errors = errors;
}
return response;
});
});
};
Now inside my onCompleted callback I get my data as well as errors. You will have to tweak your types a bit, because seems there is no errors field on response.data by default.
Mind that if you use onError from Apollo and return something from the link, it will retry your request containing errors!

Observable from Subject

I'm trying to create actions from updates from a RX Subject
It's working but I get the error below.
Here is my Epic
export function uploadSceneFile(action$, store) {
return action$.ofType(CREATE_SCENE_SUCCESS)
.mergeMap(({payload}) =>
UploadSceneWithFile(payload)
.subscribe(res => {
if (res.progress > 0)
store.dispatch(uploadSceneProgress(res))
else if(res.progress === -1){
store.dispatch(uploadSceneSuccess(res))
requestSceneProcessing(res).map(res => {
})
}
})
)
}
And here is the Subject
export function UploadSceneWithFile(scene){
const subject$ = new Subject()
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}),
})
uploader.uploadFile(scene.file)
return subject$
}
I read from a previous post that I'm supposed to be using .map, not .subscribe but nothing happens if I don't subscribe (the upload doesn't happen)
What's the best way of doing this?
subscribeToResult.js:74 Uncaught TypeError: You provided an invalid object where a stream was expected. You can provide an Observable, Promise, Array, or Iterable.
at Object.subscribeToResult (subscribeToResult.js:74)
at MergeMapSubscriber../node_modules/rxjs/operators/mergeMap.js.MergeMapSubscriber._innerSub (mergeMap.js:132)
at MergeMapSubscriber../node_modules/rxjs/operators/mergeMap.js.MergeMapSubscriber._tryNext (mergeMap.js:129)
at MergeMapSubscriber../node_modules/rxjs/operators/mergeMap.js.MergeMapSubscriber._next (mergeMap.js:112)
at MergeMapSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at FilterSubscriber../node_modules/rxjs/operators/filter.js.FilterSubscriber._next (filter.js:89)
at FilterSubscriber../node_modules/rxjs/Subscriber.js.Subscriber.next (Subscriber.js:89)
at Subject../node_modules/rxjs/Subject.js.Subject.next (Subject.js:55)
at createEpicMiddleware.js:60
at createEpicMiddleware.js:59
at SafeSubscriber.dispatch [as _next] (applyMiddleware.js:35)
at
The problem is that you subscribe inside mergeMap and return a Subscription which is invalid. The callback needs to return only Observable, Promise, Array, or Iterable.
I'm not sure what exactly you need to do but if you need to perform some side-effects you can use do() operator instead of subscribing.
export function uploadSceneFile(action$, store) {
return action$.ofType(CREATE_SCENE_SUCCESS)
.mergeMap(({ payload }) => UploadSceneWithFile(payload)
.do(res => {
...
})
)
}
Or it looks like you could put do after mergeMap as well:
export function uploadSceneFile(action$, store) {
return action$.ofType(CREATE_SCENE_SUCCESS)
.mergeMap(({ payload }) => UploadSceneWithFile(payload))
.do(res => {
...
});
}

How to get the data from BehaviorSubject after its completed?

I have a function that returns a BehaviorSubject but when I try to use the data I get back from the function I need to use it once all the data is back, is there a way to know when the BehaviorSubject is done pulling all the data?
I tried using .finally but it never gets called. Here is the code I'm using.
getData() {
let guideList = '';
this.getChildren(event.node)
.subscribe(
function(data) {
console.log('here');
guideList = data.join(',');
},
function(err) {
console.log('error');
},
function() {
console.log('done');
console.log(guideList);
}
);
}
getChildren(node: TreeNode) {
const nodeIds$ = new BehaviorSubject([]);
//doForAll is a promise
node.doForAll((data) => {
nodeIds$.next(nodeIds$.getValue().concat(data.id));
});
return nodeIds$;
}
Attached is a screen shot of the console.log
Easiest way is to just collect all the data in the array and only call next once the data is all collected. Even better: don't use a subject at all. It is very rare that one ever needs to create a subject. Often people use Subjects when instead they should be using a more streamlined observable factory method or operator:
getChildren(node: TreeNode) {
return Observable.defer(() => {
const result = [];
return node.doForAll(d => result.push(d.id)).then(() => result);
});
}

VueResource Vue.http.get Response Status Code 0

im having this issue where i send a request to the API to retrieve all users, the login function is called(index.vue) when called it tries to go to api/users/all which in this case should return all the users in that collection.
using Postman the API returns the correct results and if i console.log the output in the routeUsers before i send the response back, it outputs all the correct data to the console
when it returns to index.vue, the response status code is 0.
ive had a look online and some things are mentioning about CORS Headers but i dont think thats applicable to me and other things about the response has been cancelled,
can anyone shed some light on this for me and help me try to fix it?!
API main.js
var app = express();
var users = require('./routes/routeUsers');
app.use('/users', users);
module.exports = app;
api/models/users.js
var db = require('../Utilities/db')
module.exports.all = function(cb) {
var collection = db.get().collection('users')
collection.find().toArray(function(err, docs) {
cb(err, docs)
})
}
api/routes/routeUsers.js
var express = require('express')
, router = express.Router()
var user = require('../models/users');
router.get('/all', function(req, res) {
user.all(function(err, users) {
res.send(users);
})
})
Index.vue
export default {
data: function () {
return {
username: '',
password: '',
users: []
}
},
methods: {
login: function() {
Vue.http.get('/api/users/all').then((response) => {
console.log("SUCCESS",response);
this.users = response.body;
console.log(users);
}, function (error) {
console.log("Error", error.status); // handle error
});
}
}
};
The issue was that the inputs were in a form tag. removed Form tag and worked fine.

Resources