i use laravel6,vue. in my project i use vue2Dropzone.
i made photo update fuction. but it does not work.
I want to load and delete the image of the server on dropzone.
but after delete image on dropzone and i refresh page or go to another page delete method called as many images as it does.
i cant solve this problem.
In chrome network tab, Requests are generated by the number of photoLen in loadPhoto .
enter image description here
photoEdit.vue
<div class="mt-4">
<vue-dropzone ref="myVueDropzone" id="dropzone" :options="dropzoneOptions" #vdropzone-removed-file="imageRemoved"></vue-dropzone>
</div>
data(){
dropzoneOptions: {
url: `/api/photo/${this.$route.params.id}`,
addRemoveLinks: true,
dictRemoveFile: 'delete',
createImageThumbnails: true,
thumbnailWidth: 150,
parallelUploads: 50,
autoProcessQueue: true,
maxFileSize: 100,
timeout: 100000,
maxFiles: 50,
maxThumbnailFilesize: 100,
uploadMultiple: true,
dictDefaultMessage: "click and drag",
acceptedFiles: 'image/*',
headers: {
"X-CSRF-TOKEN": document.head.querySelector("[name=csrf-token]").content,
}
},
}
mounted() {
this.loadPhoto();
},
methods:{
loadPhoto() {
axios.get(this.apiUrl).then((response) => {
this.photo = response.data.data[0];
var photoLen = this.photo.photo_images.length;
console.log(photoLen);
for (var i = 0; i < photoLen; i++) {
var file = {size: 123, name: this.photo.photo_images[i].image_name};
var url = this.photo.photo_images[i].path;
this.$refs.myVueDropzone.manuallyAddFile(file, url);
}
}).catch(error => {
this.$router.push({name: 'adminPhoto'});
});
},
//vdropzone-removed-file called when dismount the component
imageRemoved(file, error, xhr) {
// alert(file);
//todo 해당경로로 갈시 삭제
var name = file.name;
console.log(file);
axios.post('/api/photo/delete',{
image_name : name,
})
.then((response) => {
console.log(response);
}, (error) => {
// error callback
console.log(error);
})
var _ref;
return (_ref = file.previewElement) != null ? _ref.parentNode.removeChild(file.previewElement) : void 0;
},
}
Related
I am trying to add action buttons to the push notifications sent via the firebase admin SDK to my Ionic 4 app using the Firebase-X native plugin to handle push notifications. My app is running on android and ios.
Here's my current script that sends me successfully a push notification:
exports.sendDebugPush = functions.pubsub.schedule('* * * * *').onRun((context) => {
let promises: Promise<any>[] = [];
return admin.database().ref('/users/******').once("value")
.then( user => {
let todos = [];
for(let key in user.val().nextActions) {
if(user.val().nextActions[key].active != false) {
let todo = user.val().nextActions[key]
todo['todoid'] = key;
todos.push(todo);
}
}
if(todos.length > 0) {
//currently we pick a random todo, later on the one with the highest priority
//todos.sort((a, b) => (a.priority/1 < b.priority/1) ? 1 : -1);
let randomTodo = todos[Math.floor(Math.random()*todos.length)]
let payload: any = {
notification: {
title: "Gossik",
body: "Hoiiiii " + new Date().toISOString()
},
data: {
title: "Gossik",
body: "Hoiiiii " + new Date().toISOString(),
target: 'todo',
todoid: randomTodo.todoid
}
};
Object.values(user.val().devices).forEach( (device) => {
promises.push(admin.messaging().sendToDevice(String(device), payload));
});
}
return Promise.all(promises)
.then( () => {
console.log('success!');
})
.catch( error => {
console.log('failed :(');
console.log(error);
});
});
});
Of course, without action buttons. And this function handles the push notifications in my app (this.firebase = FirebaseX plugin imported from 'import { FirebaseX } from "#ionic-native/firebase-x/ngx";'):
initPushNotifications() {
this.firebase.getToken().then(token => {
this.db.saveDeviceToken(this.auth.userid, token);
});
this.firebase.onMessageReceived().subscribe(data => {
if(!data.target) {
let title = '';
if(data.title) {
title = data.title;
} else if(data.notification && data.notification.title) {
title = data.notification.title;
} else if(data.aps && data.aps.alert && data.aps.alert.title) {
title = data.aps.alert.title;
}
let body = '';
if(data.body){
body = data.body;
} else if(data.notification && data.notification.body){
body = data.notification.body;
} else if(data.aps && data.aps.alert && data.aps.alert.body){
body = data.aps.alert.body;
}
this.alertCtrl.create({
message: title + ' ' + body,
buttons: [
{
text: "Ok"
}
]
}).then( alert => {
alert.present();
});
} else {
this.goToToDoPage(data.todoid);
}
});
}
It does this also successfully. I achieved to handle the click on the push notification such that it redirects to my To-Do page for this kind of push notification (one with a 'target' property). But now I'd like to add two action buttons 'Start' and 'Skip' on the push notification to start or skip the corresponding to-do. To be clear, I am talking about a background push notification, so the app is not open. The user then gets a standard push notification on his phone and there I'd like two action buttons to take an action without opening the app itself.
I tried various things with the payload to first even show me action buttons, but didn't achieve it. For example, the following is not working for me:
let payload: any = {
notification: {
title: "Gossik",
body: "Hoiiiii " + new Date().toISOString()
},
data: {
title: "Gossik",
body: "Hoiiiii " + new Date().toISOString(),
target: 'todo',
todoid: randomTodo.todoid,
"actions": [
{ "icon": "approve_icon", "title": "APPROVE", "callback": "AppComponent.approve", "foreground": true},
{ "icon": "reject_icon", "title": "REJECT", "callback": "AppComponent.reject", "foreground": true}
]
}
};
Thanks a lot in advance for your help and let me know if something is still unclear. :)
I am trying to access a table in DynamoDB which is hosted in Europe (Ireland) eu-west-1, from a lambda endpoint which is hosted in US East (N. Virginia) us-east-1 - however, I am always getting the error:
{
"message": "Requested resource not found",
"code": "ResourceNotFoundException",
"time": "2020-07-05T22:13:17.145Z",
"requestId": "6SGPGDFVN6AE4QMC5A8LG2RJ0JVV4KQNSO5AEMVJF66Q9ASUAAJG",
"statusCode": 400,
"retryable": false,
"retryDelay": 27.110475966612935
}
this is my code my code to call the DB:
class DynamoDB {
constructor() {
this.region = 'eu-west-1';
this.endpoint = 'https://dynamodb.eu-west-1.amazonaws.com';
this.tableName = 'MyTableName';
this.docClient = new AWS.DynamoDB.DocumentClient();
}
getUser(userId) {
return new Promise((resolve, reject) => {
const params = {
TableName: this.tableName,
Key: {
"id": userId,
}
}
this.docClient.get(params, function(err, data) {
if (err || !data.Item) {
console.error("Unable to read item. Error JSON:", JSON.stringify(err, null, 2));
return reject(JSON.stringify(err, null, 2))
} else {
console.log("GetItem data succeeded:", JSON.stringify(data, null, 2));
resolve(data.Item);
}
});
});
}
}
const DynamoDB = require("../Libraries/DynamoDB");
const $ = new DynamoDB;
const Interceptor = {
async process(session) {
return $.getUser(session.id).then(data => {
console.log(`User gotten! ${JSON.stringify(data, null, 2)}`);
}).catch(err => {
console.log(`Failure getting user... ${err}`);
};
}).finally(async () => {
await InitGameSettings();
});
}
When I attempt this using an endpoint that is hosted in the same region as the DynamoDB table - it works fine! Only when I try this using different regions does it break. Why is this?
Looks like the SDK is not using the DDB region and endpoint that you configured. Could you try replacing the constructor() with the following code snippet?
constructor() {
this.region = 'eu-west-1';
this.endpoint = 'https://dynamodb.eu-west-1.amazonaws.com';
this.tableName = 'MyTableName';
this.ddbService = new AWS.DynamoDB({
apiVersion: '2012-08-10',
endpoint: this.endpoint,
region: this.region
});
this.docClient = new AWS.DynamoDB.DocumentClient({
service: this.ddbService
});
}
I'm new to Vuejs. I want to have a form using which you can add products. The product image goes to firebase storage but how do I associate that image with the exact product in the database?
I've already set up my form, and created two methods. saveProduct() to save the products to the database and onFilePicked() to listen for changes in the input field and target the image and upload that to storage.
import { fb, db } from '../firebaseinit'
export default {
name: 'addProduct',
data () {
return {
product_id: null,
name: null,
desc: null,
category: null,
brand: null,
image: null,
}
},
methods: {
saveProduct () {
db.collection('products').add({
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
})
.then(docRef => {
this.$router.push('/fsbo/produkten')
})
},
onFilePicked (event) {
let imageFile = event.target.files[0]
let storageRef = fb.storage().ref('products/' + imageFile.name)
storageRef.put(imageFile)
}
}
}
what about this, you can use the filename, your images are going to be served as somefireurl.com/{your_file_name} on your product collection you can have an image prop with the imageFile.name.
methods: {
saveProduct (image = null) {
let productRef = db.collection('products').doc(this.product_id)
const payload = {
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
}
if (image) payload['image'] = image
return productRef
.set(payload, {merge: true})
.then(docRef => {
this.$router.push('/fsbo/produkten')
})
},
onFilePicked (event) {
let imageFile = event.target.files[0]
let storageRef = fb.storage().ref('products/' + imageFile.name)
storageRef.put(imageFile)
return this.saveProduct(imageFile.name)
}
}
That should be enough to get you started, maybe you want to try a different combination, or maybe you dont want to call saveProduct the way I set it, it's up to your use case but the idea is the same. Hope this can help you
I fixed it myself. Here's my solution. I don't know if it's technically correct but it works for my use case.
methods: {
saveProduct () {
let imageFile
let imageFileName
let ext
let imageUrl
let key
let task
db.collection('products').add({
product_id: this.product_id,
name: this.name,
desc: this.desc,
category: this.category,
brand: this.brand
})
.then(docRef => {
key = docRef.id
this.$router.push('/fsbo/produkten')
return key
})
.then(key => {
if(this.image !== null) {
this.onFilePicked
imageFile = this.image
imageFileName = imageFile.name
ext = imageFileName.slice(imageFileName.lastIndexOf('.'))
}
let storageRef = fb.storage().ref('products/' + key + '.' + ext)
let uploadTask = storageRef.put(imageFile)
uploadTask.on('state_changed', (snapshot) => {}, (error) => {
// Handle unsuccessful uploads
}, () => {
uploadTask.snapshot.ref.getDownloadURL().then( (downloadURL) => {
db.collection('products').doc(key).update({ imageUrl: downloadURL})
});
});
})
},
onFilePicked (event) {
return this.image = event.target.files[0]
}
}
upload image using file transfer in ionic 3 works fine on android,
but give me error on iOS when try it in simulator ..
* this is the error:
My Ionic Code:
chooseImageFromGallery()
{
this.type="0"
const options: CameraOptions = {
quality: 60,
destinationType: this.camera.DestinationType.FILE_URI,
encodingType: this.camera.EncodingType.JPEG,
mediaType: this.camera.MediaType.PICTURE,
saveToPhotoAlbum:true,
sourceType:0
}
this.camera.getPicture(options)
.then((imageData) => {
if (this.platform.is('ios'))
{
this.base64Image = imageData;
}
else
{
this.base64Image = imageData;
}
this.uploadimage(); // this function to upload img to server
},
(err) => {
}).then((path)=>{
})
}
uploadimage(){
this.photoSrc="";
this.translate.get("uploading Image...").subscribe(
value => {
this.sucesss=false
const fileTransfer: FileTransferObject = this.transfer.create();
let options: FileUploadOptions = {
fileKey: "file",
fileName:'test',
chunkedMode:false,
mimeType:"image/jpeg",
headers:{
Connection:"close"
},
httpMethod: "POST",
}
//------------ android ------------//
this.base64Image =this.base64Image
//------------ ios ------------//
//this.base64Image =this.base64Image.substring(28)
fileTransfer.upload(this.base64Image,encodeURI('mydomain/api/Product/upload'), options)
.then((data:any) => {
alert("upload success ")
}, (err) => {
this.translate.get( "error in upload Data").subscribe(
value => {
this.service.presentToast(value,2000)
}
)
})
})
}
using asp.net api2 .. My server Code :
[HttpPost]
[Route("upload")]
[AllowAnonymous]
public HttpResponseMessage uploadImage()
{
var request = HttpContext.Current.Request;
if (Request.Content.IsMimeMultipartContent())
{
foreach (string file in request.Files)
{
var postedFile = request.Files[file];
if (postedFile != null && postedFile.ContentLength > 0)
{
string root = HttpContext.Current.Server.MapPath("~/ServerImg");
root = root + "/" + postedFile.FileName;
postedFile.SaveAs(root);
//Save post to DB
return Request.CreateResponse(HttpStatusCode.Found, new
{
error = false,
status = "created",
path = root
});
}
else
{
return Request.CreateResponse(HttpStatusCode.NotFound, new
{
error = true
});
}
// var title = request.Params["title"];
}
// }
return null;
}
else
{
return Request.CreateResponse(HttpStatusCode.Forbidden, new
{
error = true
});
}
}
I spend more than 4 days.. but nothing is work for me ..
And this code works fine on Android but not iOS I don't know what's the wrong, I tried real iPhone and Xcode simulator and not worked
always upload error {"code":3... "http_status":500,..
Can anyone Help me please...
I've seen this problem in many places but I can't seem to find a solution. So I have defined a Kendo grid with CRUD operations the thing is that the previous fired operations get fired again.
Say you delete entry X and then you add entry Y, the create operation fires and after that the delete operation (for X - which has been deleted) fires again. Same thing if you first create an element and then edit another, it edits the 2nd element and then it re-fires the 1st create statement and inserts a duplicate for the 1st inserted element. If you go on an on with several operations a nightmare happens with all the other previous operations being fired and sent to the controller.
My grid is:
function InitializeIPAddressesGrid(userID) {
selectedUserID = userID;
$(".ipAddresses").kendoGrid({
dataSource: IPAdressesDataSource,
sortable: {
mode: "single",
allowUnsort: false
},
remove: function (e) {
this.refresh();
var canDelete = confirm("Are you sure you want to delete this record?");
if (!canDelete) {
e.preventDefault();
}
},
height: 420,
resizable: true,
pageable: {
refresh: true,
pageSize: 10
},
selectable: "row",
toolbar: ["create"],
editable:{mode: "inline", confirmation:false} ,
columns: [{
field: "IpAddress",
title: "IP Address"
},
{
field: "Status",
title: "Status"
},
{
field: "LockedUntil",
title: "Locked until",
template: "#=kendo.toString(LockedUntil, 'yyyy/MM/dd' )#"
},
{ command: ["edit", "destroy"], title: " ", width: "180px" }
]
});
}
var IPAdressesDataSource = new kendo.data.DataSource({
type: "json",
serverPaging: true,
serverSorting: true,
serverFiltering: true,
pageSize: 10,
//scrollable:false,
transport: {
read: {
url: websiteRootUrl + '/PortalAuthorization/GetIPAddressesList',
},
update: {
url: websiteRootUrl + "/PortalAuthorization/UpdateIP",
dataType: "json",
type: 'POST',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
create: {
url: websiteRootUrl + "/PortalAuthorization/CreateIP",
dataType: "json",
type: 'POST',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
destroy: {
url: websiteRootUrl + "/PortalAuthorization/DeleteIP",
dataType: "json",
type: 'DELETE',
complete: function (e) {
if (e.status != 200) {
alert(eval('(' + e.responseText + ')').Message);
}
}
},
parameterMap: function (options, operation) {
if (operation == "update" && options) {
return {ipAddress: options.IpAddress ,
status: options.Status ,
lockedUntil: kendo.toString(options.LockedUntil, 'yyyy/MM/dd' ),
pkey: options.ID,
databaseID: selectedDatabaseID };
}
else
if (operation == "destroy" && options)
{
return {
databaseID: selectedDatabaseID,
pkey: options.ID,
userIDParam: selectedUserID
};
}
else
if (operation == "create" && options) {
return {ipAddress: options.IpAddress ,
status: options.Status ,
lockedUntil: kendo.toString(options.LockedUntil, 'yyyy/MM/dd' ),
pkey: options.ID,
userIDParam: selectedUserID,
databaseID: selectedDatabaseID };
}
else
{
options.databaseID = selectedDatabaseID;
options.userID = selectedUserID;
return options;
}
}
},
schema: {
model: {
id: "ID",
fields: {
IpAddress: { type: "string" },
Status: { type: "string" },
LockedUntil: { type: "date" }
}
},
data: function (data) {
return data.Items;
},
total: function (data) {
return data.TotalCount;
}
}
});
My controllers are:
public object UpdateIP(int databaseID, long pkey, string status, string lockedUntil, string ipAddress)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
public object DeleteIP(int databaseID, long pkey, int? userIDParam)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
public object CreateIP(int databaseID, long? pkey, string status, string lockedUntil, string ipAddress, int? userIDParam)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = "...";
repository.ExecuteNonQuery(query);
return new HttpResponseMessage(HttpStatusCode.OK);
}
Do you have any ideea? where I've done something wrong? thanks in advance. P.S. the queries in the controllers work fine.
I fixed the problem, followed OnaBai's suggestion of returning the Updated/Created entity, and in the case of a Delete I returned the ID of the deleted entry.
public object UpdateIP(int databaseID, long pkey, string status, string lockedUntil, string ipAddress)
{
var database = [...];
DynamicDataRepository repository = [...];
string query = [...];
IPList updatedIP = new IPList { ID = pkey, IpAddress = ipAddress, Status = status, LockedUntil = DateTime.Today };
return Json(updatedIP, JsonRequestBehavior.AllowGet);
// return new HttpResponseMessage(HttpStatusCode.OK);
}
Only one mention: in the case of a CREATE, the method didn't seem to work so what I did is in the .complete event of the CREATE operation I did a ipGrid.dataSource.read();
ipGrid.refresh(); - so the operation doesn't repeat itself. ( I read that in this case there might be problem with the model definition - setting the ID field - but I did set that one). Many thanks to OnaBai