I am making a web app With Polymer. I make a POST request and then fill an object, then I'm making a databind to fill the data attribute needed in the google-chart tag I'm using.
<dom-module id="leads-chart" bind>
<template>
<google-chart
id="leadschart"
type='column'
data={{datagraph}}>
</google-chart>
</template>
<script>
Polymer({ is: "leads-chart",
properties:{
params:{
type: Object
},
command:{
type: String,
value: "SP_GetLead12Meses"
},
datagraph:{
type: Object,
computed: 'getBargraph(command,params)'
}
},
getBargraph: function(command,params){
var options = {
hostname: 'localhost',
path: '/',
port: 8081,
secure: false,
method: 'POST',
headers: {
'x-powered-by': 'HTTPClient.js'
},
'Content-Type': 'application/json'
}
var dictionary = new Object();
var outter = [];
const that = this;
var example1 = new HTTPClient(options)
example1.post("/executeGraph1?command="+ command + "¶m1=" + params.user, function (err, res, body) {
body = JSON.parse(body);
outter.push(['Mes','Leads',{"role":"style"}]);
for(var k in body){
var inner = [];
inner.push(dictionary[body[k]['MES']]);
inner.push(body[k]['LEADS']);
inner.push("#00A6d4");
outter.push(inner);
}
});
return outter;
}
});
The problem is the chart is not showing any data. The browser shows the following message:
The weirdest thing is that this error at the beggining was present in rare ocations but now I get it every time I load the page. Does someone know why is it happening and how to solve it?
I have made some debugging and found out the post message is answering the request with the correct information.
the object is being filled with data but the message is still there and chart is still empty
Related
I am unable to post a yaml throught http in js. The code works when I used JSON.stringify(text) for body and have content-type application/json. If I use YAML stringify, body on server side is just {}.
I have areatext where I enter a text (like yaml format) in html e.g.
martin:
name: Martin D'vloper
job: Developer
skill: Elite
Client:
$('#create-yaml2').on('click',async function () {
var text = $('#yaml-create').val();
// console.log(text)
var textYAML = YAML.stringify(text);
var options = {
hostname: 'myhostname',
port: 80,
path: `/api/postyaml`,
method: 'POST',
body: textYAML,
headers: {
'Content-Type': 'text/x-yaml'
}
};
var executeReq = http.request(options);
executeReq.write(textYAML);
executeReq.end();
});
EDIT:
Function in server side, that prints not an empty {} when posting JSON.
exports.functionCalled = async function (req, res) {
console.log('\n\n\n\n')
console.log(req.body)
console.log('\n\n\n\n')
try {
res.send(`RECEIVED`);
} catch (upgradeErr) {
res.status(422).json({
message: `Failed`,
error: upgradeErr
});
}
}
You already have a string coming from HTML, so you don't need to call YAML.stringify once again - text is already a string.
$('#create-yaml2').on('click',async function () {
var text = $('#yaml-create').val();
// console.log(text)
var textYAML = text;
var options = {
hostname: 'myhostname',
port: 80,
path: `/api/postyaml`,
method: 'POST',
body: textYAML,
headers: {
'Content-Type': 'text/x-yaml'
}
};
var executeReq = http.request(options);
executeReq.write(textYAML);
executeReq.end();
});
You may want to do something like
$('#create-yaml2').on('click',async function () {
var text = $('#yaml-create').val();
try {
YAML.parse(text)
} catch(e) {...}
...
send request
to make sure there was a valid YAML provided
YAML.stringify converts a JavaScript data structure to a string containing YML.
You don't have a JavaScript data structure, you just a string containing YML.
Almost. You have an error in it. You can't use a raw ' in a YML string that isn't quoted.
So:
Fix your YML:
martin:
name: "Martin D'vloper"
job: Developer
skill: Elite
Don't double encode it:
var textYAML = $('#yaml-create').val();
I want to use the chrome proxy API. I have this code in my background script but it will not work
const proxyData = []
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then( (response) => {
console.log(response.data)
proxyData.push(response.data)
})
}
fetchProxyData();
var config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: proxyData.ip,
port: proxyData.port
}
}
}
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${proxyData}`)
})
I get this error in background page console: background.js:55 Uncaught TypeError: Invalid invocation
I've tried with the example provided with the proxy api documentation and the error will not occur. Maybe it's caused by the config object? To set the proxy as you can see in the code, I'm using an ajax call, maybe is this the problem?
is there any fix?
I have also faced the same problem when I find the solution, it was silly mistake.
I had passed string value to port.
Please make sure you are passing integer value to port
Close. Couple things.
One, you need to fetch your data before calling Chrome's proxy API. And two, your getting the properties for your config from the proxyData array, not the JSON object from your axios call.
You need to do something like this:
const proxyData = [];
const fetchProxyData = () => {
axios({
method: "GET",
baseURL: "https://api.getproxylist.com/proxy",
params: {
protocol: "http",
allowsPost: 1,
allowsHttps: 1,
anonimity: "high anonymity"
}
}).then((response) => {
const {data} = response;
proxyData.push(data);
const config = {
mode: "fixed_servers",
rules: {
singleProxy: {
host: data.ip,
port: data.port
}
}
};
chrome.proxy.settings.set({
value: config,
scope: "regular"
}, () => {
console.log(`proxy configured with data: ${data}`)
});
})
};
fetchProxyData();
What's happening with your code...The properties host and port in singleProxy (in config) are being assigned undefined because those properties don't exist in the array proxyData. They exist in the object returned from your axios call (above, data).
The undefined keys caused Chrome to throw an Invalid Invocation error.
For anyone else getting the Invalid Invocation issue, it seems to me the problem usually lies within the config your passing into Chrome. In particular the types of each key.
In my case, I was passing in the port as a string when it needed to be a number.
I am trying to use computed attribute in Polymer but I always get an empty value. In this case I have an attribute in my custom element called datagraph. And I make a post request to a server, get a JSON file, calculate the result and then show it. This is my custom element:
<dom-module id="cost-card">
<template>
<style>
p.datos3{
color: #10cebc;
text-align: center;
font-size: 22px;
margin-top: 0px;
}
</style>
<p class="datos3">{{datagraph}}</p>
</template>
<script>
Polymer({
is: "cost-card",
properties:{
usr:{
type: Number,
value: 2
},
command:{
type: String,
value: "SP_GetCostoCampania"
},
datagraph:{
type: Number,
computed: 'getCost(command,usr)'
}
},
getCost: function(command,usr){
var options = {
hostname: 'localhost',
path: '/',
port: 8081,
secure: false,
method: 'POST',
headers: {
'x-powered-by': 'HTTPClient.js'
},
'Content-Type': 'application/json'
}
var innerCost;
var example1 = new HTTPClient(options);
example1.post("/executeGraph1?command="+ command + "¶m1=" + usr, function (err, res, body) {
body = JSON.parse(body);
innerCost = body[0].price * body[0].exchengeRate;
});
return innerCost;
}
});
</script>
</dom-module>
I have an express server running, information is being delivered correctly but the {{datagraph}} tag keeps empty. I think it may be because the post request is an anychronous task, and the value is being delivered later but I have also tried using Promise with the same result.
Does anyone know the proper way to do this?
As you've hinted, getCost is always going to return undefined because return innerCost is going to execute before the post's callback.
Computed properties are meant to take in other properties as arguments and are designed to be synchronous. If getCost took in some argument, even then you would want to use an observer that directly sets this.datagraph within the callback.
Since you aren't feeding any arguments into getCost, I would suggest you instead use a ready callback that makes the post request and sets this.datagraph within the callback.
For example:
Polymer( {
is: "cost-card",
properties: {
usr: { type: Number, value: 2 },
command: { type: String, value: "SP_GetCostoCampania" },
datagraph: Number
},
observers: [ "getCosto(command, usr)" ],
getCosto: function ( command, usr ) {
var options = {
hostname: "localhost",
path: "/",
port: 8081,
secure: false,
method: "POST",
headers: { "x-powered-by": "HTTPClient.js" },
"Content-Type": "application/json"
};
const uri = `/executeGraph1?command=${command}¶m1=${usr}`;
new HTTPClient( options ).post( uri, ( err, res, body ) => {
// values have changed, ignore result (ideally cancel the HTTP request)
if ( command !== this.command || usr !== this.usr ) return;
body = JSON.parse( body );
this.datagraph = body[ 0 ].price * body[ 0 ].exchengeRate;
} );
}
} );
I currently have a database with 2 objects:
Role
Permission
ONE Role can have MANY permissions. I currently have my Role adapter setup as:
export default DS.RESTAdapter.extend(DataAdapterMixin, {
namespace: 'v1',
host: ENV.APP.API_HOST,
authorizer: 'authorizer:application',
pathForType: function(type) {
return 'staff/roles';
}
});
By default, when a Permission is added to a Role, it generates this request:
Request:
PUT /v1/staff/roles/1
Body:
{
"name": "name_of_role"
"permissions": [
{
"id": "3",
"name": "name_of_permission"
},
...
]
}
I'd like to customize my adapter to produce a request that looks like this instead:
Request:
PUT /v1/staff/roles/1/permissions/3
Body:
<None>
Can someone please tell me how I can go about doing this? Updating the server api to accommodate Ember JS is unfortunately not an option.
UPDATE:
Based on Ryan's response, here's a (I'll call it messy) workaround that did the trick for me.
Open to suggestions for making this more elegant:
export default DS.RESTAdapter.extend(DataAdapterMixin, {
namespace: 'v1',
host: ENV.APP.API_HOST,
authorizer: 'authorizer:application',
pathForType: function(type) {
return 'staff/roles';
},
updateRecord: function(embestore, type, snapshot) {
var roleID = snapshot.id;
var permissionID = snapshot.adapterOptions.permissionID;
var url = ENV.APP.API_HOST + "/v1/staff/roles/" + roleID + "/permissions/" + permissionID;
return new Ember.RSVP.Promise(function(resolve, reject){
Ember.$.ajax({
type: 'PUT',
url: url,
headers: {'Authorization': 'OAUTH_TOKEN'},
dataType: 'json',
}).then(function(data) {
Ember.run(null, resolve, data);
}, function(jqXHR) {
jqXHR.then = null; // tame jQuery's ill mannered promises
Ember.run(null, reject, jqXHR);
});
});
},
});
I can't find it in the Ember documentation but there is a universal ajax method attached to adapter that you can override.
So in my adapter to fit our auth scheme I've done this:
export default DS.RESTAdapter.extend({
host: ENV.host,
ajax: function(url, method, hash){
if(hash){
if(hash.data !== undefined && hash.data !== null){
hash.data.sessionId = this.getSessionId();
}
}else {
hash = {
data: {}
};
hash.data.sessionId = this.getSessionId();
}
return this._super(url, method, hash);
},
getSessionId: function(){
return window.sessionStorage.getItem('sessionId') || {};
}
}
This attaches the sessionId to every ajax call to the server made though out the entire application.
Changing it to modify your url based on the hash arguments passed in shouldn't be an issue.
My version of ember is 2.3.2 but I'm on the latest stable(2.5.2) version of ember-data and this is still working great in case you are worried about the age of that blog post I found.
I am trying to combine the examples here, here to write a vows test for my node.js / express app that:
Creates a new user object
Checks the response was sane
Uses the returned _id to test looking up the newly created user
Again uses the _id to test updating the user
Item 1 and 2 work fine, but there is something wrong with my sub-context 'GET /users/:id'. It errors and I cannot figure out why. Tried Googling and using the debugger, but I still can't see what it is, I am probably just overlooking something obvious.
···✗ Errored » 3 honored ∙ 1 errored
Can anyone tell me why the 4th vow errors?
Here's my vows code:
var vows = require('vows')
, assert = require('assert')
, tobi = require('tobi')
var suite = vows.describe('Users API')
, now = new Date().getTime()
, newUser = { name: now + '_test_user', email: now + '#test.com' }
, browser = tobi.createBrowser(3000, 'localhost')
, defaultHeaders = { 'Content-Type': 'application/json' }
function assertStatus(code) {
return function (res, $) {
res.should.have.status(code)
}
}
var client = {
get: function(path) {
return function() {
browser.get(path, { headers: defaultHeaders }, this.callback)
}
},
post: function(path, data) {
return function() {
browser.post(path, { body: JSON.stringify(data), headers: defaultHeaders }, this.callback)
}
}
}
suite.addBatch({
'GET /users': {
topic: client.get('/users'),
'should respond with a 200 ok': assertStatus(200)
},
'POST /users': {
topic: client.post('/users', newUser),
'should respond with a 200 ok': assertStatus(200),
'should return the new user': function(res, $){
assert.isNotNull(res.body._id)
assert.isNotNull(res.body.created_at)
assert.isTrue(res.body._id.length > 0)
assert.equal(newUser.name, res.body.name)
assert.equal(newUser.email, res.body.email)
},
'GET /users/:id': { // Sub-context of POST /users
topic: function(res) { return client.get('/users/' + res.body._id) },
'should respond with a 200 ok': assertStatus(200)
}
}
})
suite.export(module)
EDIT
I tried simplifying the code as follows to help see if this.callback was the problem, but the error is still there:
'GET /users/:id': { // Sub-context of POST /users
topic: function(res) {
console.log('About to request /users/' + res.body._id)
browser.get('/users/' + res.body._id, { headers: defaultHeaders }, this.callback)
},
'should respond with a 200 ok': assertStatus(200)
}
How are you populating res for the fourth tes?? It wouldn't be visible outside the line
'should return the new user'
Try creating the id variable outside the addBatch call, and set it in the third test. then call
client.get('/users/' + id)
EDIT:
Better yet, put it back into newUser in the third test:
'should return the new user': function(res, $){
newUser.id = res.body._id
....
and then do:
client.get('/users/' + newUser.id)