Uploading image file from React Native to Django - django

So on the React Native side the console.log is printing this for the image file as in I'm doing console.log(photos[1]) and getting this
{"fileName": "rn_image_picker_lib_temp_0d752f09-0fab-40f0-8c89-13dec3695de0.jpg", "fileSize": 374466, "height": 810, "type": "image/jpeg", "uri": "file:///data/user/0/com.cheersfe/c
ache/rn_image_picker_lib_temp_0d752f09-0fab-40f0-8c89-13dec3695de0.jpg", "width": 1000}
Here is my React Native Code
const createFormData = (photos, body = {}) => {
const data = new FormData();
if (photos.length > 1) {
console.log(photos[1])
data.append("images", photos[1]);
}
Object.keys(body).forEach((key) => {
data.append(key, body[key]);
});
return data;
};
const onAddButtonClick = () => {
if (value === null) {
Alert.alert("Hold On!", "Please select a goal");
} else if (descriptionText === "") {
Alert.alert("Hold On!", "Update description required");
}
setLoading(true);
const body = createFormData(photos, { join_goal: value, body: descriptionText });
postGoalUpdatePost(body).then(response => {
// navigation.navigate("PostsScreen");
setLoading(false);
}).catch(error => {
const errorMessage = `${error.name}: ${error.message}`;
});
setLoading(false);
};
export async function postGoalUpdatePost(body) {
return constructConfig().then(config => {
return axios.post(`${url}/posts/update`, body, config).then(response => {
return response.data;
});
});
}
But on the Django side when I look at request.data['images'] I get this crazy hexstring:
\x7f.x�������uJr|�����a=e��|�\x00��^�=J0�^������\x08\x1a\\\x02;�H�a�a�\x19=�u�K\x01�x䞧�\x0e�{{�\x07\x14���}H�2\x06?.)%�\x7f\x1f�\x0c�RvI������=H-���[��䌏ÿ^��\x00玵�$��<g�\x1d}�\x1d�\x00®7�\x1e���Yr\x7f�\x1f���+&��wт�I�?������$�Ӯz���N?Z�+�\x07�Oo\x7f�?����\x7f\x13���ܒ1����\r����V=J0M�\x7f5�I5�ϹVG���\x189��`�\x7fJ�$��u�1���{\x7f.�չ:7���kuO��\x15���m,����{\x18x�\x7f.]�\x7f�W��s�\x0e=��1�\x00֬�e^��0y$sӧ�\x0ez՛���\x7f3YS\x13��|��+�\x7f\x13��#���;>�k�o�\x7fñ\x1c�\x03�\x0f\x18�;s�\'��ߥ\x19$$�{���O���SI�\x1b�U\x1f�\x0f�O�\x15���}^����֥\x08���u���\x002��|����|���Y�$�\x003�^�A�9�>�j��\x1f����z\x1f��U��\x17�u=z\x10\\��O����b9�V\x18\x04p\x08������Vd�G\x1f��2O�V��\x1f�ک\\u?C��qԛJI[���zT"����_�W+�\x02\x06\x0f$u����\x00����\x15\x19�\x1f��4W\x0b��z$w���'
so clearly it's coming in as a string rather than a file. How do I fix this?

The issue was the format that the upload library was saving the json
{"fileName": "rn_image_picker_lib_temp_0d752f09-0fab-40f0-8c89-13dec3695de0.jpg", "fileSize": 374466, "height": 810, "type": "image/jpeg", "uri": "file:///data/user/0/com.cheersfe/c
ache/rn_image_picker_lib_temp_0d752f09-0fab-40f0-8c89-13dec3695de0.jpg", "width": 1000}
needs to be in
{'name': file_name, 'uri': uri, 'type': type}
format. Then needed 'content-type' to be 'multipart/form-data'

Related

Unit test a nestJS interceptor

My interceptor intercepts a GET request and adds a header to the response based on some conditions.
My Controller
#UseInterceptors(ServiceHeaderInterceptor)
#Get('users')
public async users(
#Query('id') Id: number,
#Query('name') Name: string,
){
const setFlags: MetaFlags = {setCacheHeader: false, setServiceHeader: false};
const data = await this.service.getUsers(id, name, setFlags);
return data;
}
My interceptor looks like this
#Injectable()
export class HeaderInterceptor implements NestInterceptor {
public intercept(
context: ExecutionContext,
next: CallHandler,
): Observable<any> {
return next.handle().pipe(
map((data: { data: DataType, header: 'cache' | 'database' }) => {
const req = context.switchToHttp().getResponse();
if (data.header === 'database') {
res.setHeader('x-api-key', 'pretty secure');
} else {
res.setHeader(xyz, value);
}
return data.data;
}),
);
}
}
This is my test class
const users = [
{
'id': 1,
'name': 'Adam',
},
{
'id': 2,
'name': 'Evan',
},
]
const executionContext: any = {
switchToHttp: jest.fn().mockReturnThis(),
getResponse: jest.fn().mockReturnThis(),
setHeader: jest.fn().mockReturnThis(),
};
const next = {
handle: () => of(users),
};
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [
{
provide: UserService,
useValue: mock<UserService>(),
},
ServiceHeaderInterceptor,
],
}).compile();
interceptor = module.get(ServiceHeaderInterceptor);
});
it('get users',async () => {
interceptor.intercept(executionContext, next).subscribe({
next: (value) => {
expect(value).toEqual(users);
},
error: (error) => {
throw error;
},
});
});
});
Is there a way to check what my header values are at this point?
I am able to access only the response body and not the headers.
I need to verify if the header I set in the interceptor is available and has the correct value

Redirection in Edge extension

I made an Edge extension which task is to redirect the page to another site in specific at certain sites and when the user click a button this second site redirect back to the origin.
This extension works in local network but a small error.
The two site redirect to each other continously.
Somewhere I read it that Edge remove sessionStorage and localStorage in case of redirection in local network so I tried cookie but not much success.
Well I ask for help in this case.
//background.js
const apps = [
['AAA', 'aaa.intra.abc.xx']
];
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
const url = tabs[0].url;
const domain = (new URL(url)).hostname.replace('www.','').toLowerCase();
try {
chrome.cookies.get({ 'url': tabs[0].url, 'name': domain },
function(data){
if (!data) {
const i = apps.findIndex(u => domain.includes(u[1]));
if (i > -1) {
chrome.cookies.set({
url: tabs[0].url,
name: domain,
value: apps[i][0]
});
chrome.tabs.update( tabs[0].id, { url: `http://popup.intra.abc.xx?title=${apps[i][0]}`} );
}
}
}
);
} catch (e) {
alert("Error: " + e);
}
});
});
SOLUTION
manifest.json
{
"manifest_version": 2,
"name": "PopUp",
"version": "1.0",
"background": { "scripts": ["background.js"] },
"permissions": ["webRequest", "webRequestBlocking", "cookies", "<all_urls>"]
}
background.js
const apps = [
['AAA', 'aaa.intra.abc.xx']
];
function logURL(requestDetails) {
const domain = (new URL(requestDetails.url)).hostname.replace('www.','').toLowerCase();
chrome.cookies.get({ 'url': requestDetails.url, 'name': 'status' },
function(data){
if (data === null) {
const i = apps.findIndex(u => domain.includes(u[1]));
if (i > -1) {
chrome.cookies.set({
url: requestDetails.url,
name: "status",
value: "opened"
});
const url = 'http://popup.intra.abc.xx/?title=' + apps[i][0];
chrome.tabs.update( requestDetails.tabId, { url: url} );
}
}
}
);
}
chrome.webRequest.onBeforeRequest.addListener(
logURL,
{urls: ["https://...", "http://.../*", "http://.../*"]},
["blocking"]
);
I had to play with the place of URLs because they should had had better place in the manifest.json permissions array but in case of some URLs it caused ping-pong effect again. So they stayed in onBeforeRequest urls array.
manifest.json
{
"manifest_version": 2,
"name": "PopUp",
"version": "1.0",
"background": { "scripts": ["background.js"] },
"permissions": ["webRequest", "webRequestBlocking", "cookies", "<all_urls>"]
}
background.js
const apps = [
['AAA', 'aaa.intra.abc.xx']
];
function logURL(requestDetails) {
const domain = (new URL(requestDetails.url)).hostname.replace('www.','').toLowerCase();
chrome.cookies.get({ 'url': requestDetails.url, 'name': 'status' },
function(data){
if (data === null) {
const i = apps.findIndex(u => domain.includes(u[1]));
if (i > -1) {
chrome.cookies.set({
url: requestDetails.url,
name: "status",
value: "opened"
});
const url = 'http://popup.intra.abc.xx/?title=' + apps[i][0];
chrome.tabs.update( requestDetails.tabId, { url: url} );
}
}
}
);
}
chrome.webRequest.onBeforeRequest.addListener(
logURL,
{urls: ["https://...", "http://.../*", "http://.../*"]},
["blocking"]
);
I had to play with the place of URLs because they should had had better place in the manifest.json permissions array but in case of some URLs it caused ping-pong effect again. So they stayed in onBeforeRequest urls array.

chart js not dispalying data array that comes from an axios request

I have an API end point that returns an array of 24 values that I want to use in my chartjs within a vue component.
when the page loads I get no errors but the bars on the charts just don't show and I don't know why.
EDIT: I noticed that the async function returns a promise instead of the actual data:
async filterData() {
await this.$axios.get('/api/data_app/job_count_by_hour/')
.then(response => {
return this.chart_data = response.data;
})
}
here is the data return code, I have a function that populates the chart_data array :
data(){
return {
form:{
day: 'select day',
workspace:'',
machine_family: [],
duration: []
},
res: [],
total:[],
chart_data: [],
url: '/api/jobs/job_count_by_hour/',
days: ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "sunday"],
barChart2: {
labels: ["6h", "7h", "8h", "9h","10h","11h", "12h", "13h", "14h", "15h", "16h", "17h", "18h", "19h", "20h", "21h","22h", "23h", "00h"],
datasets: [{
label: ["popularity"],
backgroundColor:"#f93232" ,
data: this.chart_data
},],
},
}
},
methods: {
async filterData() {
let _url = `${this.url}`
await this.$axios.get(_url)
.then(response => {
this.chart_data = response.data;
})
return this.chart_data
},
},
mounted() {
this.filterData()
}
}
this is the chart component:
<script>
import { Line } from 'vue-chartjs'
export default {
extends: Line,
props: {
chartdata: {
type: Object,
default: null
},
options: {
type: Object,
default: null
}
},
mounted () {
this.renderChart(this.chartdata, this.options)
}
}
in the parent component It looks like this:
en <BarChart :labels="barChart2.labels"
:datasets="barChart2.datasets"
:height="100"
>
</BarChart>ter code here
Turns out that when you try to update nested data, the component doesn't re-render.
This is how I solved it, I put the entire object in an update function and call that function when i get my data from the back end, I hope this helps!:
methods: {
onInput(value) {
this.filterData()
},
updateChart(data) {
this.datasets = [{
label: ["popularity"],
backgroundColor:"#f93232",
data: data
}]
},
async loadData() {
await this.$axios.get(this.url)
.then(response => {
this.updateChart(response.data)
})
},
},
mounted() {
this.loadData()
},

AWS XRay Tracing - Not Displaying Trace Map or SubSegments

I am trying to trace a serverless express Lambda function using AWSXRay.
I have tried several different approaches to this and nothing seems to work.
If I leave out the aws-xray-sdk-express middleware, I will see all my segments in the Timeline, and see my Lambda function appearing twice in the Trace Map. If I include the express middleware, I will see the middleware segment ('Super Dooper Trace Function') in the Trace Map and just the first subsegment ('MyFirstTrace') in the Timeline (not in the Trace Map).
I am trying to get all Subsegments to appear in both the Timelines and Node Graphs
const AWSXray = require('aws-xray-sdk');
const xrayExpress = require('aws-xray-sdk-express');
const express = require('express');
const awsServerlessExpress = require('aws-serverless-express');
module.exports.handler = async (event, context) => {
const app = express();
app.use(xrayExpress.openSegment('Super Dooper Trace Function'));
app.get('/test', async (req, res) => {
const result = await doWork();
res.send(result);
});
app.use(xrayExpress.closeSegment());
const server = awsServerlessExpress.createServer(app);
return awsServerlessExpress.proxy(server, event, context, 'PROMISE').promise;
}
const doWork = async () => {
const res1 = await traceMyFunction('MyFirstTrace', 3000)
const res2 = await traceMyFunction('MySecondTrace', 3000);
const res3 = await traceMyFunction('MyThirdTrace', 2000);
return [res1, res2, res3];
}
const traceMyFunction = (name, delayMs) => {
return trace(name, async () => {
return delay(delayMs)
});
}
function trace(name, promiseFunction) {
return new Promise((resolve, reject) => {
AWSXray.captureAsyncFunc(name, (subSegment) => {
promiseFunction(subSegment)
.then((result) => {
resolve(result);
subSegment.close();
}).catch((e) => {
subSegment.close();
reject(e)
});
});
});
}
const delay = (ms) => {
return new Promise((res, rej) => {
setTimeout(() => res({ time: ms }), ms)
});
};
This is the resultant XRay Trace
And this is the Trace Raw Data
{
"Duration": 8.278,
"Id": "1-5e2f6cc3-a99e6c08f02ce0aec7ab7121",
"Segments": [
{
"Document": {
"id": "87ca46b60ded68e1",
"name": "Super Dooper Trace Function",
"start_time": 1580166338.92,
"end_time": 1580166347.198,
"http": {
"request": {
"url": "http://localhost/test",
"method": "GET",
"user_agent": "",
"client_ip": ""
},
"response": {
"status": 200
}
},
"aws": {
"xray": {
"sdk": "X-Ray for Node.js",
"sdk_version": "2.5.0",
"package": "aws-xray-sdk"
}
},
"service": {
"version": "unknown",
"runtime": "node",
"runtime_version": "v12.13.0",
"name": "unknown"
},
"trace_id": "1-5e2f6cc3-a99e6c08f02ce0aec7ab7121",
"subsegments": [
{
"id": "98e9f32273700e6e",
"name": "MyFirstTrace",
"start_time": 1580166339.078,
"end_time": 1580166342.082
}
]
},
"Id": "87ca46b60ded68e1"
}
]
}
Serverless Express has known incompatabilities with the current X-Ray SDK - due to the fact Lambda generates its own Segment, then the Express middleware tries to create one as well. We're planning to address this in the near future.
https://github.com/aws/aws-xray-sdk-node/issues/45
For the full explanation, see this thread: https://github.com/aws/aws-xray-sdk-node/issues/30

JSON Validate check based on response from arrayElement

I wanted to check from the response format if status=AVAILABLE then arrayElement should return with roomTypeId else roomTypeId should not return for other status.
[
{
"status": "SOLDOUT",
"propertyId": "dc00e77f",
"Fee": 0,
"isComp": false
},
{
"roomTypeId": "c5730b9e",
"status": "AVAILABLE",
"propertyId": "dc00e77f",
"price": {
"baseAveragePrice": 104.71,
"discountedAveragePrice": 86.33
},
"Fee": 37,
"isComp": false
},
]
[
{
"status": "SOLDOUT",
"propertyId": "773000cc-468a-4d86-a38f-7ae78ecfa6aa",
"resortFee": 0,
"isComp": false
},
{
"roomTypeId": "c5730b9e-78d1-4c1c-a429-06ae279e6d4d",
"status": "AVAILABLE",
"propertyId": "dc00e77f-d6bb-4dd7-a8ea-dc33ee9675ad",
"price": {
"baseAveragePrice": 104.71,
"discountedAveragePrice": 86.33
},
"resortFee": 37,
"isComp": false
},
]
I tried to check this from below;
pm.test("Verify if Status is SOLDOUT, roomTypeId and price information is not returned ", () => {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
if (arrayElement.status == "SOLDOUT")
{
pm.expect(arrayElement).to.not.include("roomTypeId");
}
else if (arrayElement.status == "AVAILABLE")
{
pm.expect(arrayElement).to.include("roomTypeId");
}
});
});
You need to check if the property exists or not.
With the have.property syntax you can do that.
You can read the Postman API reference docs and also Postman uses a fork of chai internally, so ChaiJS docs should also help you.
Updated script:
pm.test("Verify if Status is SOLDOUT, roomTypeId and price information is not returned ", () => {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
if (arrayElement.status === "SOLDOUT") {
pm.expect(arrayElement).to.not.have.property("roomTypeId");
} else if (arrayElement.status === "AVAILABLE") {
pm.expect(arrayElement).to.have.property("roomTypeId");
}
});
});