I tried to define the url which opens when user click on notification but it continue go to url('/')
only . I send the new url with payload.data but I did not know where I can define this route in the client side so it opens when user click notification .
I use laravel-notification-channels/fcm
/**
* #param Model $notifiable
* #return FcmMessage
*/
final public function toFcm(Model $notifiable): FcmMessage
{
return FcmMessage::create()
->setData(array_merge(['type' => $this->fcmNotification->type],$this->fcmNotification->data)
)->setNotification(\NotificationChannels\Fcm\Resources\Notification::create()
->setTitle($this->fcmNotification->title)
->setBody($this->fcmNotification->body)
->setImage($this->fcmNotification->image)
) ->setAndroid(
AndroidConfig::create()
->setFcmOptions(AndroidFcmOptions::create()->setAnalyticsLabel('analytics'))
->setNotification(AndroidNotification::create()->setColor('#0A0A0A'))
)->setApns(
ApnsConfig::create()->setFcmOptions(ApnsFcmOptions::create()->setAnalyticsLabel('analytics_ios')));
}
##################### firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/7.23.0/firebase-messaging.js');
/*
firebase.initializeApp({
apiKey: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
authDomain: "xxxxxxxxxxxxxxxxxxxxxxxxxxxx",
projectId: "xxxxxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxxx",
appId: "x",xxxxxxxxxxxxxxxxxxxxxxxxx
measurementId: "xxxxxxxxxxxxxxxx"
});
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function(payload) {
console.log(
"[firebase-messaging-sw.js] Received background message ",
payload,
);
/* Customize notification here */
const notificationTitle = "Background Message Title";
const notificationOptions = {
body: "Background Message body.",
icon: "/itwonders-web-logo.png",
};
return self.registration.showNotification(
notificationTitle,
notificationOptions,
);
});
##################### main layout
$(document).ready(function () {
const firebaseConfig = {
apiKey: "xxxxxxxxxxxxx",
authDomain: "x",xxxxxxxxxxxxxxxxxxxx
projectId: "xxxxxxxxxxxxxxxxxxxx",
storageBucket: "xxxxxxxxxxxxxxxxxxxx",
messagingSenderId: "xxxxxxxxxxxxxxxxxxxx",
appId: "xxxxxxxxxxxxxxxxxxxx",
measurementId: "xxxxxxxxxxxxxxxxxxxx"
};
firebase.initializeApp(firebaseConfig);
const messaging = firebase.messaging();
function initFirebaseMessagingRegistration() {
messaging
.requestPermission()
.then(function () {
return messaging.getToken()
})
.then(function (token) {
// console.log(token);
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$.ajax({
url: '{{ theme_route('save.fcm.token')}}',
type: 'POST',
data: {
token: token
},
dataType: 'JSON',
success: function (response) {
console.log('Token saved successfully.');
},
error: function (err) {
console.log('User Token Error' + err);
},
});
}).catch(function (err) {
console.log('User Chat Token Error' + err);
});
} initFirebaseMessagingRegistration();
messaging.onMessage(function (payload) {
const noteTitle = payload.notification.title;
console.log(payload.data);
const noteOptions = {
body: payload.notification.body,
icon:"{{website()->logo}}" ,
image: payload.notification.image,
};
new Notification(noteTitle, noteOptions);
self.addEventListener('notificationclick', function(event) {
event.notification.close();
console.log('test click event');
event.waitUntil(self.clients.openWindow('#'));
});
});
});```
I figured that I should look for " PushEvent " : I used this two listeners to handle user clicks on FCM web push notifications, in your service worker firebase-messaging-sw.js place the following
two listeners (of course change them depending on your data) :
self.addEventListener("push", (event) => {
console.log(event);
let response = event.data && event.data.text();
let title = JSON.parse(response).notification.title;
let body = JSON.parse(response).notification.body;
let icon = JSON.parse(response).notification.image;
let image = JSON.parse(response).notification.image;
event.waitUntil(
self.registration.showNotification(title, { body, icon, image, data: { url: JSON.parse(response).data.url } })
)
});
self.addEventListener('notificationclick', function(event) {
event.notification.close();
event.waitUntil(
clients.openWindow(event.notification.data.url)
);
});
Related
The notification is showing fine, but when I click on it, or any of the actions, nothing happens. I see no logging, no error messages, but the notification does close (although it closes even when I comment out the event.notification.close()).
I've tried using the Chrome debugger, and I can set a break point in the code that shows the notification, but all breakpoints within the notificationclick handler fail to pause execution.
I've spent days trying to get this to work and I'm at my wits' end.
const auth = firebase.auth();
const functions = firebase.functions();
const done = functions.httpsCallable("done");
const snooze = functions.httpsCallable("snooze");
self.addEventListener("notificationclick", event => {
console.log("notificationclick", event);
const uid = auth.currentUser.uid;
const { id, url } = event.notification.data;
event.notification.close();
event.waitUntil(() => {
switch (event.action) {
case "done":
console.log("Done");
return done({ uid, id });
case "snooze1":
console.log("Snooze 1 Hour");
return snooze({ uid, id, hours: 1 });
case "snooze24":
console.log("Snooze 1 Day");
return snooze({ uid, id, hours: 24 });
default:
console.log("Open App");
return clients
.matchAll({
includeUncontrolled: true,
type: "window"
})
.then(clientList => {
for (let i = 0; i < clientList.length; i++) {
let client = clientList[i];
if (url[0] === "#") {
if (client.url.endsWith(url) && "focus" in client) {
return client.focus();
}
} else {
if (
client.url.replace(/#.*$/, "") === url &&
"focus" in client
) {
return client.focus();
}
}
}
if (clients.openWindow) {
return clients.openWindow(location.origin + url);
}
});
}
});
});
firebase
.messaging()
.setBackgroundMessageHandler(({ data: { title, options } }) => {
options = JSON.parse(options);
options.actions = [
{ action: "done", title: "Done" },
{ action: "snooze1", title: "Snooze 1 Hour" },
{ action: "snooze24", title: "Snooze 1 Day" }
];
return self.registration.showNotification(title, options);
});
Hi Could you try below code and see if this is getting called-
self.addEventListener('notificationclick', function (event) {
event.notification.close();
var redirectUrl = null;
var tag = event.notification.tag;
if (event.action) {
redirectUrl = event.action
}
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: !0
});
var chatClient;
for (const client of allClients) {
if (redirectUrl != '/' && client.url.indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient
}
}().then(result => {
if (tag) {
//PostAction(tag, "click")
}
}))
}
});
Edited-
Attaching both js files. it is working at my end.
firebase-messaging-sw.js
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-app.js');
importScripts('https://www.gstatic.com/firebasejs/3.9.0/firebase-messaging.js');
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
const messaging = firebase.messaging();
messaging.setBackgroundMessageHandler(function (payload) {
console.log('[firebase-messaging-sw.js] Received background message ', payload.data);
var notificationTitle = payload.data.Title;
var notificationOptions = {
body: payload.data.Body,
icon: payload.data.Icon,
image: payload.data.Image,
action: payload.data.ClickAction
};
console.log("strated sending msg" + notificationOptions);
return self.registration.showNotification(notificationTitle,notificationOptions);
});
self.addEventListener('notificationclick', function (event) {
console.log('On notification click: ', event.notification);
event.notification.close();
var redirectUrl = null;
if (event.notification.data) {
if (event.notification.data.FCM_MSG) {
redirectUrl = event.notification.data.FCM_MSG.data ? event.notification.data.FCM_MSG.data.click_action : null
} else {
redirectUrl = event.notification.data ? event.notification.data.click_action : null
}
}
console.log("redirect url is : " + redirectUrl);
if (redirectUrl) {
event.waitUntil(async function () {
var allClients = await clients.matchAll({
includeUncontrolled: true
});
var chatClient;
for (var i = 0; i < allClients.length; i++) {
var client = allClients[i];
if (client['url'].indexOf(redirectUrl) >= 0) {
client.focus();
chatClient = client;
break;
}
}
if (chatClient == null || chatClient == 'undefined') {
chatClient = clients.openWindow(redirectUrl);
return chatClient;
}
}());
}
});
self.addEventListener("notificationclose", function (event) {
event.notification.close();
console.log('user has clicked notification close');
});
application.js file :
/// <reference path="scripts/jquery-3.3.1.js" />
try {
var config = {
apiKey: "your api key",
authDomain: "you firebase domain",
databaseURL: "your firbase db url",
projectId: "your project id",
storageBucket: "",
messagingSenderId: "sender id"
};
firebase.initializeApp(config);
if ('serviceWorker' in navigator && 'PushManager' in window) {
console.log('Service Worker and Push is supported');
navigator.serviceWorker
.register('/firebase-messaging-sw.js')
.then((swReg) => {
firebase.messaging().useServiceWorker(swReg);
askForPermissioToReceiveNotifications();
})
.catch(function (error) {
console.error('Service Worker Error', error);
window.alert("Service Worker Error" + error);
})
} else {
console.warn('Push messaging is not supported');
window.alert("Push messaging is not supported " + (navigator.serviceWorker));
}
const askForPermissioToReceiveNotifications = async () => {
try {
const messaging = firebase.messaging();
console.log(messaging);
await messaging.requestPermission();
const token = await messaging.getToken();
if (token !== null || token !== 'undefined') {
await sendDeviceTokenToServerSide(token);
}
console.log('Got token : ' + token);
messaging.onMessage(function (payload) {
console.log('onMessage: ', payload);
setTimeout(() => {
navigator.serviceWorker.ready.then(function (registration) {
var notificationTitle = payload.notification.title;
var notificationOptions = {
body: payload.notification.body,
data: payload.data,
icon: payload.notification.icon,
image: payload.data.Image,
requireInteraction: payload.notification.requireInteraction,
tag: payload.notification.tag,
click_action: payload.data.click_action,
requireInteraction: true
};
registration.showNotification(notificationTitle, notificationOptions);
},50)
});
});
}
catch (e) { console.log('error in getting token: ' + e); window.alert("error in getting token: " + e); }
}
function sendDeviceTokenToServerSide(token) {
$.ajax({
type: 'POST',
url: '/Home/StoreToken',
timeout: 5000000,
data: { token: token },
success: function (success) {
console.log("device token is sent to server");
},
error: function (error) {
console.log("device error sending token to server : " + error);
window.alert("device error sending token to server : " + error);
}
});
}
} catch (e) {
window.alert("error: " + e);
}
function GetFcmUserToken(messaging) {
messaging.onTokenRefresh(function () {
messaging.getToken()
.then(function (refreshedToken) {
console.log('Token refreshed.');
return refreshedToken;
})
.catch(function (err) {
console.log('Unable to retrieve refreshed token ', err);
showToken('Unable to retrieve refreshed token ', err);
});
});
}
self.addEventListener('notificationclick', function (event) {
const clickedNotification = event.notification;
// Do something as the result of the notification click
const promiseChain = clients.openWindow(clickedNotification.data.Url);
event.waitUntil(promiseChain);
});
This code inside service worker js worked fine for me on chrome Desktop and Android.
issue I have developed own API which generates and refreshes token using directline api. The problem is after that when I integrated token instead of Secret in above code, my bot replies the answer correctly but also echo back the input which is being provided. There is no such implementation done in code and with secret and emulator all works fine.
(function () {
$('head').append('<link rel="stylesheet" type="text/css" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-core/9.6.0/css/fabric.min.css">');
$('head').append('<link rel="stylesheet" type="text/css" href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css">');
$('head').append('<link rel="stylesheet" type="text/css" href="chatbot.css">');
var chatIsVisible = false;
$(function () {
$(".botwrapper").toggle();
$('<i class="ms-Icon ms-Icon--ChromeMinimize minimizeIcon" aria-hidden="true"></i>').appendTo(".wc-header");
$("#botbutton").click(function () {
chatIsVisible = true;
$("#botbutton").toggle("fade", function () {
$("#BotChatGoesHere").toggle("fade", function () {
$(".chatbot .wc-shellinput").focus();
});
});
});
$(".wc-header .minimizeIcon").click(function () {
$("#BotChatGoesHere").toggle("fade", function () { $("#botbutton").toggle("fade"); chatIsVisible = false; });
});
setTimeout(showBot, 3000);
setInterval(shakeBot, 10000);
function showBot() {
$("#botbutton").toggle("fade").effect("bounce", { times: 3 }, "slow");
}
function shakeBot() {
if (!chatIsVisible) {
$("#botbutton").effect("bounce", { times: 3 }, "slow");
}
}
});
const params = BotChat.queryParams(location.search);
const user = {
id: params['userid'] || 'userid',
name: params['username'] || 'User'
};
const bot = {
id: params['botid'] || 'SAM',
name: params['botname'] || 'SAM'
};
const speechOptions = {
speechRecognizer: new CognitiveServices.SpeechRecognizer({ locale: 'de-DE', subscriptionKey: '' }),
speechSynthesizer: new CognitiveServices.SpeechSynthesizer({
gender: CognitiveServices.SynthesisGender.Female,
subscriptionKey: '',
voiceName: 'Microsoft Server Speech Text to Speech Voice (de-DE, Stefan, Apollo)'
})
};
window['botchatDebug'] = params['debug'] && params['debug'] === 'true';
function ConnectWebBotChat() {
let headers = {
};
if (botConnection !== null) {
// for refresh token
headers = {
old_token: TokenResult.token,
user_id: TokenResult.userId
};
}
$.ajax({
url: "http://localhost:64102/api/DLToken",
//async: "false",
method: "POST",
data: "",
dataType: 'json',
contentType: "application/json",
headers: headers,
success: function (result, status, jqXHR) {
TokenResult = result;
botConnection = new BotChat.DirectLine({
domain: params['domain'],
secret: result.token,
token: result.token,
webSocket: params['webSocket'] && params['webSocket'] === 'true'
});
BotChat.App({
bot: bot,
resize: 'detect',
user: user,
speechOptions: speechOptions,
directLine: botConnection
}, document.getElementById('BotChatGoesHere'));
PingBotConnection(true);
console.log("SAM Connection Refreshed : " + status);
},
error(jqXHR, textStatus, errorThrown) {
console.log("SAM Connection Refresh : " + errorThrown);
}
});
}
function PingBotConnection(_IsFirstTime = false) {
botConnection
.postActivity({
from: user,
name: 'Connection Test',
type: 'event',
value: ''
})
.subscribe(function (id) {
console.log('SAM Pinged OK!');
});
botConnection.connectionStatus$
.subscribe(connectionStatus => {
handleConnection(connectionStatus);
if (!_IsFirstTime)
ConnectWebBotChat();
});
}
function handleConnection(connectionStatus) {
switch (connectionStatus) {
case 0:
console.log("SAM Uninitialized");
break;
case 1:
console.log("SAM Connecting");
break;
case 2:
console.log("SAM Online");
break;
case 3:
console.log("SAM ExpiredToken");
break;
case 4:
console.log("SAM FailedToConnect");
break;
case 5:
console.log("SAM Ended");
break;
}
}
let botConnection = null;
let TokenResult = null;
ConnectWebBotChat();
setInterval(() => { PingBotConnection(false); }, 1780000);
})();
Bot should not echo back the inputted message on use of Directline Token.
Many thanks in Advance
Looking at the above posted code, it looks like you are passing the token as a secret. I would recommend you just pass one not both.
Also, I would recommend you to upgrade to web chat v4 as it provides more support when it comes to customization. This sample provides a detailed guide on how to migrate from Web Chat v3 to v4.
i want to send image to a server and getting the result with a json format but the application returns a Network Request failed error
react native 0.6 using genymotion as emulator
i tried RNFetchblob but the result take a long time to get response (5 min )
also i tried axios but it response with empty data with 200 ok
this is the function that import the image
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
avatarSource: source,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
and this method that sends the image
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.avatarSource , name:'file.jpeg'});
fetch(url, {
method: 'POST',
body:UplodedFile
})
.then(response => response.json())
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});
i expect json format
ScreenShot here
can you change your code like this?
OnClick = () => {
ImagePicker.showImagePicker(options, response => {
console.log("Response = ", response);
if (response.didCancel) {
console.log("User cancelled image picker");
} else if (response.error) {
console.log("Image Picker Error: ", response.error);
} else {
let source = { uri: response.uri };
// You can also display the image using data:
//let source = { uri: 'data:image/jpeg;base64,' + response.data };
this.setState({
pickerResponse: response,
data: response.data,
BtnDisabled: false
});
console.log();
}
});
};
Send = async () => {
let url = "http://web001.XXX.com:8000/api/prediction/check_prediction/";
let UplodedFile = new FormData();
UplodedFile.append('file',{ type:'image/jpeg', uri : this.state.pickerResponse.path , name:'file.jpeg'});
axios({
method: "post",
url: url,
data: UplodedFile
})
.then(response => {
console.log("success");
console.log(response);
})
.catch(error => {
console.error(error);
});
I need send mails with nodemailer using ajax for show a message confirmation, with out reload my page.
other problem is if using the code ajax in the frontend send two mails
============================
app.js
app.post('/enviar', function(req,res){
var name = req.body.nombre;
var mail = req.body.correo;
var messege = req.body.mensaje;
var mail_from = "servicios#fractalservicios.com";
var subject_from = "Contact web fractal nodejs";
var transporter = nodemailer.createTransport(smtpTransport({
host: "*****",
port: ***,
auth: {
user: "****",
pass: "****"
}
}));
var mailOptions = {
from: name + ' ' + mail, // sender address
to: mail_from, // list of receivers
subject: subject_from , // Subject line
html: messege // html body
};
transporter.sendMail(mailOptions,function(error,result){
if(error){
console.log(error);
console.log("salio mal");
//res.end("error");
res.render('error',{titulo: 'error al enviar menmsaje'});
}else{
console.log("Message sent: " + res.message);
console.log("correcto");
res.redirect('/');
//res.render('enviado',{titulo: 'mensaje enviado'});
}
//res.redirect('/');
});
})
build.js => Front-end
var nombre = $('#nombre').val();
var correo = $('#correo').val();
var mensaje = $('#mensaje').val();
var enviar_info = {
"nombre": nombre,
"correo": correo,
"mensaje": mensaje
};
$('.send_mail').on('click',function(){
$.ajax({
type: "POST",
url: "/enviar",
data: JSON.stringify(enviar_info),
contentType:"application/json; charset=utf-8",
dataType: 'json',
success: function(e){
alert("genial se envio tu mensaje");
}
});
});
I recently ran into the same issue and I tried the following way. It worked like a magic for me, late answer but, I am sure someone else might need it...
$(function() {
$('#contact-form').on('submit', function(event) {
event.preventDefault();
let name = $('input[name="name"]').val(),
company = $('input[name="company"]').val(),
email = $('input[name="email"]').val(),
phone = $('input[name="phone"]').val(),
message = $('textarea[name="message"]').val();
$.ajax({
url: '/',
method: "POST",
contentType: 'application/json',
data: JSON.stringify({
name,
company,
email,
phone,
message
}),
success: function(response) {
console.log(response);
},
fail: function(error) {
console.log(error);
}
});
});
});
and in server.js
app.post('/', function(req, res) {
const output = `
<p>You have a new contact request</p>
<h3>contact details</h3>
<ul>
<li>Name: ${req.body.name}</li>
<li>Company: ${req.body.company}</li>
<li>Email: ${req.body.email}</li>
<li>Phone: ${req.body.phone}</li>
</ul>
<h3>Message</h3>
<p>${req.body.message}</p>
`;
let transporter = nodemailer.createTransport({
service: 'gmail',
host: 'mail.domain.com',
port: 465,
tls: {
rejectUnauthorized: false, //NOTE: you only need to set rejectUnauthorized to false if you are running on a local server, you can remove it after testing
}
});
let mailOptions = {
from: `nodemailer contact ${req.body.email}`,
to: 'info#domain.com',
subject: 'User Form Contact',
html: output
};
transporter.sendMail(mailOptions, function(error, info) {
if (error) {
return console.log(error);
}
console.log('Message sent: %s', info.messageId);
console.log('Preview URL: %s', nodemailer.getTestMessageUrl(info));
res.send({
msg: 'Email has been sent!'
});
});
});
Looking at the Flux Documentation I can't figure out how the code to a ajax update, and a ajax fetch would fit into the dispatcher, store, component architecture.
Can anyone provide a simple, dummy example, of how an entity of data would be fetched from the server AFTER page load, and how this entity would be pushed to the server at a later date. How would the "complete" or "error" status of request be translated and treated by the views/components? How would a store wait for the ajax request to wait? :-?
Is this what you are looking for?
http://facebook.github.io/react/tips/initial-ajax.html
you can also implement a fetch in the store in order to manage the information.
Here is an example (it is a concept, not actually working code):
'use strict';
var React = require('react');
var Constants = require('constants');
var merge = require('react/lib/merge'); //This must be replaced for assign
var EventEmitter = require('events').EventEmitter;
var Dispatcher = require('dispatcher');
var CHANGE_EVENT = "change";
var data = {};
var message = "";
function _fetch () {
message = "Fetching data";
$.ajax({
type: 'GET',
url: 'Url',
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = error;
MyStore.emitChange();
}
});
};
function _post (myData) {
//Make post
$.ajax({
type: 'POST',
url: 'Url',
// post payload:
data: JSON.stringify(myData),
contentType: 'application/json',
success: function(data){
message = "";
MyStore.emitChange();
},
error: function(error){
message = "update failed";
MyStore.emitChange();
}
});
};
var MyStore = merge(EventEmitter.prototype, {
emitChange: function () {
this.emit(CHANGE_EVENT);
},
addChangeListener: function (callback) {
this.on(CHANGE_EVENT, callback);
},
removeChangeListener: function (callback) {
this.removeListener(CHANGE_EVENT, callback);
},
getData: function (){
if(!data){
_fetch();
}
return data;
},
getMessage: function (){
return message;
},
dispatcherIndex: Dispatcher.register( function(payload) {
var action = payload.action; // this is our action from handleViewAction
switch(action.actionType){
case Constants.UPDATE:
message = "updating...";
_post(payload.action.data);
break;
}
MyStore.emitChange();
return true;
})
});
module.exports = MyStore;
Then you need to subscribe your component to the store change events
var React = require('react');
var MyStore = require('my-store');
function getComments (){
return {
message: null,
data: MyStore.getData()
}
};
var AlbumComments = module.exports = React.createClass({
getInitialState: function() {
return getData();
},
componentWillMount: function(){
MyStore.addChangeListener(this._onChange);
},
componentWillUnmount: function(){
MyStore.removeChangeListener(this._onChange);
},
_onChange: function(){
var msg = MyStore.getMessage();
if (!message){
this.setState(getData());
} else {
this.setState({
message: msg,
data: null
});
}
},
render: function() {
console.log('render');
return (
<div>
{ this.state.message }
{this.state.data.map(function(item){
return <div>{ item }</div>
})}
</div>
);
}
});
I hope it is clear enough.