I'm lost trying to upload a file using restangular.js as part of a multi-part form.
This is the error I get:
XPCWrappedNative_NoHelper { message: "JavaScript component does not have a method named: "available"'JavaScript component does not have a method named: "available"' when calling method: [nsIInputStream::available]", result: 2153185328, name: "NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED", filename: "https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.js", lineNumber: 8407, columnNumber: 0, location: XPCWrappedNative_NoHelper, inner: null, data: null } angular.js:9899
XPCWrappedNative_NoHelper { message: "JavaScript component does not have a method named: "available"'JavaScript component does not have a method named: "available"' when calling method: [nsIInputStream::available]", result: 2153185328, name: "NS_ERROR_XPC_JSOBJECT_HAS_NO_FUNCTION_NAMED", filename: "https://ajax.googleapis.com/ajax/libs/angularjs/1.2.17/angular.js", lineNumber: 8407, columnNumber: 0, location: XPCWrappedNative_NoHelper, inner: null, data: null }
This is my code to send the object:
$rootScope.objects.user.withHttpConfig({
transformRequest: angular.identity
},
}).customPUT($scope.objects.user, "", { // I've tried regular `put` as well
'Content-Type': undefined
}).then(function(resp) {
if (resp == "OK") {
$scope.successes = [{
msg: "Saved"
}];
}
}, function(err) {
console.log(err);
$scope.errors = err.data.errors;
});
The user object contains the following:
{
username: "...",
email: "...",
profilePicture: [File] // What makes this complicated
}
Related
I am trying to create a contact using "create or update api" from here: https://developers.activecampaign.com/reference#create-or-update-contact-new
I tried calling the cURL command which gives a proper response but while doing it from axios it gives error.
API: https://deskera4783.api-us1.com/api/3/contact/sync
Method: POST
Code:
var axios = require("axios");
var data = ({
contact: {
email: "jondoe#example.com",
firstName: "John",
lastName: "Doe",
phone: "7223224241",
fieldValues: [
{ field: "1", value: "The Value for First Field" },
{ field: "6", value: "2008-01-20" },
],
},
});
var config = {
method: "post",
url: "https://deskera4783.api-us1.com/api/3/contact/sync",
headers: {
"Api-Token":
"XXX",
"Content-Type": "application/json",
Cookie:
"cmp800513081=0c7070adc5cdc923a8922c47e98dbe77; PHPSESSID=d3e534f9b1a3f61316cd2cf89b41f164; em_acp_globalauth_cookie=caea42ae-d440-4491-9c08-d920b3378638",
},
data,
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Also, in the network tab request params are not seen neither the response is received.
Console error is:
enter image description here
I'm working with symfont and JSON Web Token and Symfony.
I'm trying to get jwt with ajax, but I get 401 (Unauthorized)
The problem is with ajax, because i try with postman and I can get the token.
here is my security.yaml
security:
encoders:
App\Entity\Users:
algorithm: bcrypt
providers:
users:
entity:
class: App\Entity\Users
property: email
firewalls:
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
login_app_manager:
pattern: ^/user/login
stateless: true
anonymous: true
provider: users
json_login:
check_path: /user/login
username_path: email
password_path: password
success_handler: lexik_jwt_authentication.handler.authentication_success
failure_handler: lexik_jwt_authentication.handler.authentication_failure
require_previous_session: false
app_api_manager:
pattern: ^/mngr/api
stateless: true
anonymous: false
provider: users
guard:
authenticators:
- lexik_jwt_authentication.jwt_token_authenticator
access_control:
- { path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, roles: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/api, roles: IS_AUTHENTICATED_FULLY }
here is my ajax
var data = {
'email':email,
'password':password
};
$.ajax({
type: "POST",
url: "/user/login",
contentType: "application/json",
data: JSON.stringify(data),
success: function(response) {
console.log(response);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
console.log('Error : ' + errorThrown);
}
});
please help me, thank you
Try post instead of ajax:
$(document).ready(function{
//form submit
$("form").submit(function(event){
var email = $('#email').val();
var password = $('#password').val();
$.post("/user/login",{
email:email, password: password
}).done(function(data){
})
})
});
In access_control add path
{ path: ^/user/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
instead of
{ path: ^/login, roles: IS_AUTHENTICATED_ANONYMOUSLY }
and make sure to include this path in routes.yaml
user_login:
path: /user/login
methods: ['POST']
The error message being received is:
"User validation failed: email: Path email is required., display_name: Path display_name is required."
The error name being sent back is: ValidationError.
The code for the ajax call is:
function submit_new_user(display_name, email, password){
let user_data = new New_User(display_name, email, password);
console.log(user_data);
$.ajax ({
dataType: 'JSON',
data: user_data,
method:'POST',
url: 'http://localhost:3001/user',
success: (res)=>{
console.log(res);
},
error: (xhr, ajaxOptions, thrownError)=>{
console.log(xhr, ajaxOptions, thrownError);
}
});
};
the console.log seen above prints:
New_User {display_name: "test", email: "test#test.com", password: "Passw0rd"}
The server route is:
app.post('/user', (req, res)=>{
let body = _.pick(req.body, ['display_name', 'email', 'password']);
let user = new User(body);
user.save().then(()=>{
return user.generateAuthToken();
}).then((token)=>{
res.header('x-auth', token).send(user);
}).catch((err)=>{
res.status(400).send(err);
});
});
This route works when pinged with Postman. The server supports cors.
The model is as follows:
var UserSchema = new mongoose.Schema({
display_name: {
type: String,
unique: true,
required: true,
validate: {
validator: (val)=>{
return /^[\w\s]+$/.test(val);
},
message: '{VALUE} is not a valid display name. Only
alphanumeric, upper and lower case characters are allowed.'
}
},
email: {
type: String,
required: true,
unique: true,
validate: {
validator: validator.isEmail,
message: '{VALUE} is not a valid email.'
}
},
password: {
type: String,
require: true,
minlength: 6
},
tokens: [{
access:{
type: String,
required: true
},
token: {
type: String,
required: true
}
}]
});
I'm still learning node.js. I was guided through the creation of the API, and am trying to build a front end on my own.
The object leaving contains the three value pairs - but the object arriving, before the server changes it, is empty. I'm at loss as to why.
SOLUTION: the problem was in the server-side bodyParser. I had forgotten to include the encoded url method. It was not parsing the JSON as it came in, since previously the API had only been tested using Postman there was no need to use the .urlencoded() method.
I'm using loopback with express session to store cartId.
But I need to inject cartId on request session in order to make my tests work.
So on my remote method I have
Cart.get = function (req, cb) {
Service.getCart(req, req.session.cartId)
.then(function (result) {
cb(null, result);
})
.catch(cb);
};
Cart.remoteMethod(
'get',
{
accepts: { arg: 'req', type: 'object', 'http': { source: 'req' } },
returns: { arg: 'cart', type: 'object', root: true },
http: { path: '/', verb: 'get' }
}
);
How can I force req.session.cartId for my tests?
Thanks
If I understand your case correctly, you can do something similar to the code below, you would just add another param (cardId) to your get method definition:
Cart.remoteMethod('get',{
accepts: [
{ arg: "caseId", type: "number", http: {source:'path'} },
{ arg: 'req', type: 'object', http: { source: 'req' } }
],
returns: { arg: 'cart', type: 'object', root: true },
http: { path: '/:caseId/getCart', verb: 'get' }
});
You can simply use "get" remote method and pass cartId through URL or if you have concern about cartId visibility on URL then you can use post method as following code.
Use following cart.js file and explore in loopback api.
module.exports = function (Cart) {
Cart.getCart = function (cartId, cb) {
Cart.findOne({
where: { cartId : cartId }
}, function (err, cart) {
cb(null, users);
});
};
Cart.remoteMethod('getCart', {
accepts: {
arg: "id",
type: "string",
required: true
},
returns: {
arg: 'cart',
type: 'object'
},
http: {
path: '/:cartId/getcart',
verb: 'get'
}
});
};
get call : http://HOST:IP/cart/YourID/getcart
You will retrieve cart by Id.
Hope this will work.
I have an image saved on a MongoDB. The model is the following:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
data: { type: Buffer, default: null },
tags: Array
}
Now I need to load the image again from the DB.
I make an AJAX call and request the picture with the id.
$.ajax({
type: "POST",
url: window.location.origin + '/picture',
contentType: 'application/json',
dataType: 'json',
async: true,
data: JSON.stringify({ id: id }),
success: function (result) {
console.log(result);
a = result;
var img = result.result[0].picture.data.join("").toString('base64');
img = "data:" + result.result[0].picture.metadata.type + ";base64," + img;
$('#img').attr('src', img);
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('error ' + textStatus + " " + errorThrown);
success = false;
}
});
And this is the handler on the server
var Picture = require('../models/picture');
Picture.find({ "_id": req.body.id}, function (err, pic) {
if (err || !pic)
res.end(JSON.stringify({ result: "error" }));
if (pic) {
console.log(pic);
res.end(JSON.stringify({ result: pic }));
}
})
I have translated the binary data into base64 but the image doesnt display.
(I had to join the binary data because they came into an array).
There are some other similar posts however they dont have anything that I havent done (I think).
As stated in the comments, it is better to have a separate endpoint in your application to make these calls "look like" standard static file requests. So the first thing I would do is change your schema a little:
picture: {
metadata: {
name: { type: String, default: null },
comment: { type: String, default: null },
publisherID: { type: String,default: null },
date: { type: Date, default: Date.now },
size: { type: Number,default: 0 },
type: { type: String, default: null }
},
path: { type: String, required: true },
mime: { type: String, required: true },
data: { type: Buffer, default: null },
tags: Array
}
So that adds two fields which are going to identify the "path" to the image to match, and "mime" as the mime-type of the file. So "path" is a more "friendly" identifier than an _id and the "mime-type" would be set in insert to match the returned content type.
Then you set up a route to serve the content:
app.get('/images/:imgname', function(req,res) {
Picture.find({ "picture.path": req.param("imgname") }, function(err,pic) {
if (err) // checking here
// Sending response
res.set('Content-Type', pic.mime);
res.send( pic[0].picture.data );
});
})
So when you did a request like:
wget http://localhost:3000/images/test.png
This would happen:
Find the document matcing "path" for "test.png"
Assign the document property for "picture.mime" as the Content-Type for the response
Send the binary data back as the response
So for the client, it's an actual file as the response, and the point is the that "browser" can cache this and not hit your application where the "cached" copy is valid.
If you are embedding Base64 encoded data in JSON responses then you loose that important part and you send the data every time. It's also a very messy process to handle, as you have discovered.