how can show data of User as advertisement ?
Unanswered
Northeast Congo Lion posted this in #help-forum
Northeast Congo LionOP
I am trying to show data as advertisement of User from Mongodb database to Next.js 14. I used client side to rotate ads in queue but its not real time.
126 Replies
Northeast Congo LionOP
can anyone help me ?
@joulev
Northeast Congo LionOP
@Chinese Alligator can you help me
Toyger
first of all don't ping users that are not part of topic.
second of all your explanation of your problem is awfull.
add details, what ads, how it shown now, how it should be, any reference to thing that you want to achieve etc...
second of all your explanation of your problem is awfull.
add details, what ads, how it shown now, how it should be, any reference to thing that you want to achieve etc...
User is adding his details and his referral link, I will show their referrals in queue as advertisement
Northeast Congo LionOP
I tried with useEffect, but its client side fetching and its not real time, I want all advertisement in sync with all users
Toyger
in your code you are not doing anything with your response, why then you even fetch it?
your pusher looks ok, do you get any messages at all through it? did you check is it work at all?
your pusher looks ok, do you get any messages at all through it? did you check is it work at all?
@Toyger in your code you are not doing anything with your response, why then you even fetch it?
your pusher looks ok, do you get any messages at all through it? did you check is it work at all?
Northeast Congo LionOP
I checked with currentAd it shows null
@Toyger in your code you are not doing anything with your response, why then you even fetch it?
your pusher looks ok, do you get any messages at all through it? did you check is it work at all?
Northeast Congo LionOP
I am using Next.js 14, I added this code in route file, do I need to use server action instead route file
I mean this , api/advertisement/getAllAds
Its printing all this values from env, so issue is not here
appId: process.env.PUSHER_APP_ID!,
key: process.env.PUSHER_KEY!,
secret: process.env.PUSHER_SECRET!,
cluster: process.env.PUSHER_CLUSTER!,
useTLS: true
appId: process.env.PUSHER_APP_ID!,
key: process.env.PUSHER_KEY!,
secret: process.env.PUSHER_SECRET!,
cluster: process.env.PUSHER_CLUSTER!,
useTLS: true
Toyger
pusher should have some kind of event logging, also you can add console.log to emitters and subscriptions to check are they working
@Toyger pusher should have some kind of event logging, also you can add console.log to emitters and subscriptions to check are they working
Northeast Congo LionOP
error :
for Adbox component :
Ad rotation triggered: Response {type: 'basic', url: 'http://localhost:3000/api/advertisement/getAllAds', redirected: false, status: 405, ok: false, …} ....
....................for Adbox component :
useEffect(() => {
fetch('/api/advertisement/getAllAds').then(response => {
console.log('Ad rotation triggered:', response);
}).catch(error => {
console.error('Error triggering ad rotation:', error);
});
console.log('Adbox pusher api start')
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
console.log('Adbox pusher api middle')
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
setCurrentAd(data.ad);
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
}, []);For currentAd state :
console.log error : Adbox pusher: null
console.log error : Adbox pusher: null
my issue is I know how to fetch data through route in Next.js but unable to do with pusher
Is my tech stack right ?
I mean pusher for real time data, I mean to fetch
I mean pusher for real time data, I mean to fetch
@Northeast Congo Lion error :
js
Ad rotation triggered: Response {type: 'basic', url: 'http://localhost:3000/api/advertisement/getAllAds', redirected: false, status: 405, ok: false, …} ....
....................
for Adbox component :
js
useEffect(() => {
fetch('/api/advertisement/getAllAds').then(response => {
console.log('Ad rotation triggered:', response);
}).catch(error => {
console.error('Error triggering ad rotation:', error);
});
console.log('Adbox pusher api start')
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
console.log('Adbox pusher api middle')
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
setCurrentAd(data.ad);
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
}, []);
Toyger
first of all here
remove
then check your route through browser.
also, from where this url triggers? if from some external source it will not have access to your localhost:3000
export default async function GET(req: Request) {remove
defaultthen check your route through browser.
also, from where this url triggers? if from some external source it will not have access to your localhost:3000
@Toyger first of all here
js
export default async function GET(req: Request) {
remove `default`
then check your route through browser.
also, from where this url triggers? if from some external source it will not have access to your localhost:3000
Northeast Congo LionOP
got it, removed it, now that 405 error gon
gone
now its 500
error
Toyger
check server logs
Northeast Congo LionOP
wait bro
what do yo mean ?
👇👇
also, from where this url triggers? if from some external source it will not have access to your localhost:3000 ?
👇👇
also, from where this url triggers? if from some external source it will not have access to your localhost:3000 ?
Toyger
I don't know where you call it, is it some webhook url, or is it some url that you call in your code.
@Toyger I don't know where you call it, is it some webhook url, or is it some url that you call in your code.
Northeast Congo LionOP
see this is api route file
Toyger
right now you need to check your pusher account and it should have some kind of logs
@Toyger right now you need to check your pusher account and it should have some kind of logs
Northeast Congo LionOP
logs in server side of Next.js
null
⨯ node_modules\pusher\lib\errors.js (13:0) @ new RequestError
⨯ unhandledRejection: Error
at new RequestError (webpack-internal:///(rsc)/./node_modules/pusher/lib/errors.js:13:16)
at eval (webpack-internal:///(rsc)/./node_modules/pusher/lib/requests.js:61:17)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Timeout.eval [as _onTimeout] (webpack-internal:///(rsc)/./app/api/advertisement/getAllAds/route.ts:31:13) {
name: 'PusherRequestError',
message: 'Unexpected status code 413',
url: 'https://api-ap2.pusher.com/apps/1791291/events?auth_key=1124eb29e2343d430175&auth_timestamp=1714565710&auth_version=1.0&body_md5=9407ca774dc5539f5b0730b8a1dd27c2&auth_signature=d050297c957aeb4b2617ab130c8c74a0b4e380a73d39baf7a859b8404405380d',
error: undefined,
status: 413,
body: 'The data content of this event exceeds the allowed maximum (10240 bytes). See https://pusher.com/docs/channels/server_api/http-api#publishing-events for more info\n'
}@Toyger right now you need to check your pusher account and it should have some kind of logs
Northeast Congo LionOP
I am checking with pusher
Toyger
The data content of this event exceeds the allowed maximum (10240 bytes)they allow only short messagees 10kb
@Toyger `The data content of this event exceeds the allowed maximum (10240 bytes)`
Northeast Congo LionOP
http errors :
The data content of this event exceeds the allowed maximum (10240 bytes). See https://pusher.com/docs/channels/server_api/http-api#publishing-events for more info
Request method: POST
The data content of this event exceeds the allowed maximum (10240 bytes). See https://pusher.com/docs/channels/server_api/http-api#publishing-events for more info
Request method: POST
My request method was GET, why its showing POST
this errors are from pusher server logs
@Northeast Congo Lion My request method was GET, why its showing POST
Toyger
you are not controlling request to pusher, you can only call trigger, which will call POST to their api with your data.
they even don't have GET handler.
they even don't have GET handler.
@Toyger you are not controlling request to pusher, you can only call trigger, which will call POST to their api with your data.
they even don't have GET handler.
Northeast Congo LionOP
can you explain this
@Northeast Congo Lion can you explain this
Toyger
it's self explanatory,
you are calling
which call POST request to pusher API, which show you error that your message bigger than allowed in API limits.
you are calling
await pusher.trigger('ad-channel', 'ad-update', {
ad
});which call POST request to pusher API, which show you error that your message bigger than allowed in API limits.
@Toyger it's self explanatory,
you are calling
js
await pusher.trigger('ad-channel', 'ad-update', {
ad
});
which call POST request to pusher API, which show you error that your message bigger than allowed in API limits.
Northeast Congo LionOP
I removed image from backend to avoid that error (size error)
now I am getting response but not image
@Toyger it's self explanatory,
you are calling
js
await pusher.trigger('ad-channel', 'ad-update', {
ad
});
which call POST request to pusher API, which show you error that your message bigger than allowed in API limits.
Northeast Congo LionOP
before:
Adbox pusher: null
Now (after) :
Adbox pusher: {_id: '6627ab3fadf957dc0af93a11', title: 'Upland', link: 'https://r.upland.me/gKuk', image: '', userId: '662
Adbox pusher: null
Now (after) :
Adbox pusher: {_id: '6627ab3fadf957dc0af93a11', title: 'Upland', link: 'https://r.upland.me/gKuk', image: '', userId: '662
but I want images also
@Northeast Congo Lion before:
Adbox pusher: null
Now (after) :
Adbox pusher: {_id: '6627ab3fadf957dc0af93a11', title: 'Upland', link: 'https://r.upland.me/gKuk', image: '', userId: '662
Toyger
probably pusher not intended for that, you probably save all of this ads in your database, so you can send via pusher only update event and in your client on message from pusher you again fetch data from api.
@Toyger probably pusher not intended for that, you probably save all of this ads in your database, so you can send via pusher only update event and in your client on message from pusher you again fetch data from api.
Northeast Congo LionOP
that's what I did, or I misconcept it
I am getting data from backend
export async function GET(req: Request) {
try {
await connectDB();
const ads = await Advertisement.find({});
console.log('ads through pusher:', ads)Toyger
you sent a lot of data, I am saying send only update event
await pusher.trigger('ad-channel', 'ad-update', {upd:1});@Toyger you sent a lot of data, I am saying send only update event
js
await pusher.trigger('ad-channel', 'ad-update', {upd:1});
Northeast Congo LionOP
what's upd: 1
Toyger
small update event
Northeast Congo LionOP
my code is :
await pusher.trigger('ad-channel', 'ad-update', {
ad
});Toyger
when you get such small update event
you refetching data from your api
@Toyger when you get such small update event
Northeast Congo LionOP
but I already sent only 1 object which is ad
@Toyger you sent a lot of data, I am saying send only update event
js
await pusher.trigger('ad-channel', 'ad-update', {upd:1});
Northeast Congo LionOP
there is nothing upd in my code
Toyger
which giant object that rejected by pusher because of size
@Toyger which giant object that rejected by pusher because of size
Northeast Congo LionOP
😂 yeah
@Toyger which giant object that rejected by pusher because of size
Northeast Congo LionOP
bro, what is upd
Toyger
so instead you send small message
upd is short for update
you can send whatever you want
it just should be small
@Toyger upd is short for update
Northeast Congo LionOP
oh, like custom message
Toyger
yes
Northeast Congo LionOP
not got this, for currentAd state
Adbox pusher: undefinedimport React, { useEffect, useState } from 'react';
import Pusher from 'pusher-js';
import Image from 'next/image';
type AdType = {
_id: string;
link: string;
image: string;
}
const AdBox = () => {
const [currentAd, setCurrentAd] = useState<AdType | null>(null);
useEffect(() => {
fetch('/api/advertisement/getAllAds').then(response => {
console.log('Ad rotation triggered:', response);
}).catch(error => {
console.error('Error triggering ad rotation:', error);
});
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
console.log('Adbox pusher api middle')
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
setCurrentAd(data.ad);
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
console.log('Adbox pusher:', currentAd)
return (
<div>
{currentAd && (
<div>
<Image src={currentAd.image} alt="Advertisement" width={300} height={300} layout="responsive" />
<a href={currentAd.link} target="_blank" rel="noopener noreferrer">Visit Ad</a>
</div>
)}
</div>
);
};
export default AdBox;for
Received ad update: {upd: 1}Toyger
if it's message from console then you get update
now you need to change
so it refetch data
and set it to your state
now you need to change
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
setCurrentAd(data.ad);
});so it refetch data
fetch('/api/advertisement/getAllAds').then(response => {
console.log('Ad rotation triggered:', response);
}).catch(error => {
console.error('Error triggering ad rotation:', error);
});and set it to your state
@Toyger if it's message from console then you get update
now you need to change
js
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
setCurrentAd(data.ad);
});
so it refetch data
js
fetch('/api/advertisement/getAllAds').then(response => {
console.log('Ad rotation triggered:', response);
}).catch(error => {
console.error('Error triggering ad rotation:', error);
});
and set it to your state
Northeast Congo LionOP
Ad rotation ads in json undefinedupdated code
fetch('/api/advertisement/getAllAds')
.then(response => {
console.log('Ad rotation triggered:', response);
response.json()
})
.then(data => {
console.log('Ad rotation ads in json', data)
setCurrentAd(data);
})
.catch(error => {
console.error('Error triggering ad rotation:', error);
});I added
route.ts
ad to pass object through responseroute.ts
export async function GET(req: Request) {
try {
await connectDB();
const ads = await Advertisement.find({});
console.log('ads through pusher:', ads)
let currentAdIndex = 0;
setInterval(async () => {
const ad = ads[currentAdIndex];
console.log(`Sending ad: ${currentAdIndex}`, ad);
await pusher.trigger('ad-channel', 'ad-update', {
upd: 1
});
currentAdIndex = (currentAdIndex + 1) % ads.length;
}, 20000);
return NextResponse.json({ message: 'Ad rotation started', ad: ads[currentAdIndex] });
} catch (error) {
console.error('Error rotating ads:', error);
}
}Northeast Congo LionOP
its only trigger event, which is pusher.trigger
not fetching data, I mean get request after each trigger
not fetching data, I mean get request after each trigger
and now its only getting undefined for
Ad rotation ads in json@Northeast Congo Lion js
Ad rotation ads in json undefined
updated code
js
fetch('/api/advertisement/getAllAds')
.then(response => {
console.log('Ad rotation triggered:', response);
response.json()
})
.then(data => {
console.log('Ad rotation ads in json', data)
setCurrentAd(data);
})
.catch(error => {
console.error('Error triggering ad rotation:', error);
});
Toyger
why do you need 2 then here? get data directly from response
@Toyger why do you need 2 then here? get data directly from response
Northeast Congo LionOP
I am getting response but its too much responses.
I will share my updated code and screenshot
I will share my updated code and screenshot
const fetchAds = async() => {
try{
const response = await axios.get('/api/advertisement/getAllAds');
console.log('response', response?.data)
setCurrentAd(response?.data?.ad)
}catch(error){
console.log('Error fetching ads:', error);
}
}
useEffect(() => {
fetchAds();
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data);
fetchAds();
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
}, []);I changed method from fetch to async await and invoke in useEffect first then also in bind method (fetchAds())
@Toyger what's wrong about it? code looks fine
Northeast Congo LionOP
its making too many request
I will show you
Toyger
based on that you receive a lot ad-update update events, then you probably generating a lot of them
Northeast Congo LionOP
changes I made is added state isFetch and use it in useEffect for if condition of fetchAds invoking
const AdBox = () => {
const [currentAd, setCurrentAd] = useState<AdType | null>(null);
const [isFetch, setIsFetch] = useState<boolean>(true);
const fetchAds = async() => {
try{
const response = await axios.get('/api/advertisement/getAllAds');
setCurrentAd(response?.data?.ad)
}catch(error){
console.log('Error fetching ads:', error);
}
}
useEffect(() => {
if(isFetch){
fetchAds();
setIsFetch(false);
}
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
fetchAds();
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
}, []);
console.log('Adbox pusher:', currentAd)
return (.....
)
}@Toyger based on that you receive a lot ad-update update events, then you probably generating a lot of them
Northeast Congo LionOP
how ?
Is here I making any mistake, in pusher.trigger?
export async function GET(req: Request) {
try {
await connectDB();
const ads = await Advertisement.find({});
console.log('ads through pusher:', ads)
let currentAdIndex = 0;
setInterval(async () => {
const ad = ads[currentAdIndex];
console.log(`Sending ad: ${currentAdIndex}`, ad);
await pusher.trigger('ad-channel', 'ad-update', {
upd: 1
});
currentAdIndex = (currentAdIndex + 1) % ads.length;
}, 60000);
console.log('ad res:', ads[currentAdIndex])
return NextResponse.json({ message: 'Ad rotation started', ad: ads[currentAdIndex] });
} catch (error) {
console.error('Error rotating ads:', error);
}
}@Northeast Congo Lion changes I made is added state isFetch and use it in useEffect for if condition of fetchAds invoking
js
const AdBox = () => {
const [currentAd, setCurrentAd] = useState<AdType | null>(null);
const [isFetch, setIsFetch] = useState<boolean>(true);
const fetchAds = async() => {
try{
const response = await axios.get('/api/advertisement/getAllAds');
setCurrentAd(response?.data?.ad)
}catch(error){
console.log('Error fetching ads:', error);
}
}
useEffect(() => {
if(isFetch){
fetchAds();
setIsFetch(false);
}
const pusher = new Pusher(process.env.NEXT_PUBLIC_PUSHER_KEY!, {
cluster: process.env.NEXT_PUBLIC_PUSHER_CLUSTER!,
forceTLS: true
});
const channel = pusher.subscribe('ad-channel');
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
fetchAds();
});
return () => {
pusher.unsubscribe('ad-channel');
channel.unbind_all();
};
}, []);
console.log('Adbox pusher:', currentAd)
return (.....
)
}
Toyger
why
this in setinterval?
setInterval(async () => {
const ad = ads[currentAdIndex];
console.log(`Sending ad: ${currentAdIndex}`, ad);
await pusher.trigger('ad-channel', 'ad-update', {
upd: 1
});
currentAdIndex = (currentAdIndex + 1) % ads.length;
}, 60000);this in setinterval?
Toyger
why?
Northeast Congo LionOP
I want to invoke data from ad array in queue, like google ads, each object contain link and image, that I want to show on frontend
Toyger
you need to stop your deployment of site because it basically generates thousands of events right now
@Toyger you need to stop your deployment of site because it basically generates thousands of events right now
Northeast Congo LionOP
I haven't deployed that updated code
don't worry
Toyger
wdym? if you receiveing events then pusher works
and eventually it will start charge money
@Toyger wdym? if you receiveing events then pusher works
Northeast Congo LionOP
and eventually it will start charge money ?
Toyger
you generating thousands of events through pusher right now
Northeast Congo LionOP
oh
yes
Toyger
you don't need setinterval, you need to trigger single update event. that's all
after that your client will fetch all new data from server
after that your client will fetch all new data from server
Northeast Congo LionOP
but how it fetch after each 1 minute
Toyger
you have code
that will fetch it as soon as receiveing upd signal
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
fetchAds();
});that will fetch it as soon as receiveing upd signal
right now you sending thousands signals and it making thousands fetches
@Toyger you have code
js
channel.bind('ad-update', function(data:any) {
console.log('Received ad update:', data); // Check the data received
fetchAds();
});
that will fetch it as soon as receiveing upd signal
Northeast Congo LionOP
but how it fech after 1 minute, I set setInterval, which was wrong approach but it fetches after 1 minute, how it hapen without it
it triggers new request, that I understand but what about timing
Toyger
why 1 minute? from where this 1 minute arise? you wanted update your ad in real time, your code without setinterval will update it in real time
@Toyger why 1 minute? from where this 1 minute arise? you wanted update your ad in real time, your code without setinterval will update it in real time
Northeast Congo LionOP
but I want in queue that list of ads
Toyger
why?
Northeast Congo LionOP
ok, I will explain you
I have users data, we can consider 1000 users
and they submit their site link and image or anything they want to promote
and its in database and I am rendering those data as advertisemnet on frontend
if there 1000 Users,
each User's advertisement will run for 1 minute, after that advertisement will change and next User's advertisement will show .
I can change time from 1 minute to 2 minutes.
each User's advertisement will run for 1 minute, after that advertisement will change and next User's advertisement will show .
I can change time from 1 minute to 2 minutes.
I use real time cause I want to show advertisement in sync, like A user will see 'xy' advertisement then B user will see same advertsement.
I tried this with client side fetching with only useEffect but it fetches from 1st each time if I open app and If I close it starts from 1st again. So its not syncing real time, right ?
I tried this with client side fetching with only useEffect but it fetches from 1st each time if I open app and If I close it starts from 1st again. So its not syncing real time, right ?
this feature I want to implement
bro, have you got my point ?
for reference this is document data
Toyger
I will not help you with implementation, you have no idea what you working with, you need to read how giant ads networks work, and gain more experience in programming.
I can give you direction, if you want to be in sync you can use user UTC as point in sync, because it will be same for everyone. and setInterval should be run on client. Using websocket for this task is useless waste of resources, especially for syncing.
I can give you direction, if you want to be in sync you can use user UTC as point in sync, because it will be same for everyone. and setInterval should be run on client. Using websocket for this task is useless waste of resources, especially for syncing.
Northeast Congo LionOP
bro, pls help me, I already waited for so long. No one knows,
atleast now its working
atleast now its working
@Toyger I will not help you with implementation, you have no idea what you working with, you need to read how giant ads networks work, and gain more experience in programming.
I can give you direction, if you want to be in sync you can use user UTC as point in sync, because it will be same for everyone. and setInterval should be run on client. Using websocket for this task is useless waste of resources, especially for syncing.
Northeast Congo LionOP
I said I want data in sync, means all users can see same advertisement not different
and for senterval, I can remove it from server side, get data in array of 10 list items, then can show on client side with setinterval
is that ok ?
or should I use other option like redis, can I do that with redis ?
Toyger
UTC will give you data in sync, as I said it same for everyone, deviation is insignificant for human eye.
redis or memcached is required.
but your "auction" of banners is bad, your clients will waste their money with such calculations, you need ton of additional logging for fair views calculation. it's not a single pusher websocket task, it's much more because people pay for view.
redis or memcached is required.
but your "auction" of banners is bad, your clients will waste their money with such calculations, you need ton of additional logging for fair views calculation. it's not a single pusher websocket task, it's much more because people pay for view.
Northeast Congo LionOP
like this
const updateCurrentAd = (ads: AdType[]) => {
const minutes = new Date().getUTCMinutes();
const currentAdIndex = minutes % ads.length;
setCurrentAd(ads[currentAdIndex]);
};const AdBox = () => {
const [ads, setAds] = useState<AdType[]>([]);
const [currentAd, setCurrentAd] = useState<AdType | null>(null);
const fetchAds = async () => {
try {
const response = await axios.get('/api/advertisement/getAllAds');
setAds(response.data.ads);
updateCurrentAd(response.data.ads);
} catch (error) {
console.error('Error fetching ads:', error);
}
};
const updateCurrentAd = (ads: AdType[]) => {
const minutes = new Date().getUTCMinutes();
const currentAdIndex = minutes % ads.length;
setCurrentAd(ads[currentAdIndex]);
};
useEffect(() => {
fetchAds();
const interval = setInterval(() => {
if (ads.length > 0) {
updateCurrentAd(ads);
}
}, 1000 * 10); // check every 10 seconds to limit checks
return () => clearInterval(interval);
}, [ads]);Toyger
something like that is minimal setup, but this still not include view amount, because each and every network and device is different it can take like 20s to fetch new data, so you need a lot of additional counter when image change, when it's loaded in DOM, how many user saw it etc......
you need to have your action alghoritm, what if new ad arrived, what if some was deleted etc......
it's freaking rabbit hole.
you need to have your action alghoritm, what if new ad arrived, what if some was deleted etc......
it's freaking rabbit hole.
Northeast Congo LionOP
if its possible on client side with UTC, I will try that.
I just want ads in syncronize for all users
see my implementation, should I do like that
const AdBox = () => {
const [ads, setAds] = useState<AdType[]>([]);
const [currentAd, setCurrentAd] = useState<AdType | null>(null);
const fetchAds = async () => {
try {
const response = await axios.get('/api/advertisement/getAllAds2');
console.log('response:', response)
setAds(response?.data?.advertisement);
updateCurrentAd(response?.data?.advertisement); // Initial update after fetch
} catch (error) {
console.error('Error fetching ads:', error);
}
};
const updateCurrentAd = (ads: AdType[]) => {
if(ads.length === 0){
setCurrentAd(null);
return;
}
const now = new Date();
const startOfDay = new Date(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate());
const millisecondsSinceStartOfDay = now.getTime() - startOfDay.getTime();
const minutesSinceStartOfDay = Math.floor(millisecondsSinceStartOfDay / 60000);
const currentAdIndex = minutesSinceStartOfDay % ads?.length;
setCurrentAd(ads[currentAdIndex]);
};
useEffect(() => {
fetchAds();
// Align to the next full minute for checking
let interval: any;
const now = new Date();
const millisecondsToNextMinute = (60 - now.getSeconds()) * 1000 - now.getMilliseconds();
setTimeout(() => {
interval = setInterval(() => {
updateCurrentAd(ads); // Reference the latest ads through closure
}, 20000); // Every 60 seconds, precisely at the start of each minute
}, millisecondsToNextMinute);
return () => clearInterval(interval);
}, []); // Empty dependency array, run only on mount
console.log('arry', ads)
return (