I'm having trouble finding good documentation about how to use javascript in order to find out if a like button is clicked or not. I can't use an on-click event because the button might already be checked when a user comes onto my page but that seems to be all I can find regarding tracking likes externally (not counting other methods that are no longer supported). Anyone have any experience with such issues? Thanks.
It depends on the Like button. If it's for a Facebook object that has an ID, you can query the like table (but you'll need user_likes permission)
If it's for a URL, it's not really possible: facebook graph api determine if user likes url [stackoverflow]
It it's for a built-in like you could use a cookie to remember the click, or save the click in your own database.
Just to expand on Gil's answer. For built-in likes you can use a batch request consisting of two request:
1) Try to like the object in question
2) If there was no error, delete the like connection
Example batch:
[{"method":"POST", "relative_url":"me/og.likes", "body":"object=<SOME_URL>", "name":"like-attempt", "omit_response_on_success": false},
{"method":"DELETE", "relative_url":"{result=like-attempt:$.id}"}]
If an object was already liked, batch response would be:
[
{
"code": 400,
"headers": [
...
{
"name": "WWW-Authenticate",
"value": "OAuth \"Facebook Platform\" \"invalid_request\" \"(#3501) User is already associated to the object object on a unique action type Like. Original Action ID: 143539809123515\""
}
],
"body": "{\n \"error\": {\n \"message\": \"(#3501) User is already associated to the object object on a unique action type Like. Original Action ID: 143539809123515\",\n \"type\": \"OAuthException\",\n \"code\": 3501\n }\n}"
},
null
]
So to check if object was liked, JSON.parse the first response body and look for an error with error code 3501. Keep in mind that the actual error code is not documented anywhere so it could change, although I don't think it is likely.
Related
I can't seem to find a solution when I get a push notification and click on it redirects me to a screen, chat, etc. link to push notification.
I would also like to add a square image to the side and could not find an answer.
The push notifications are sent from a NodeJS server I looked at the docs and search the internet and I did not find anything of interest.
https://docs.expo.dev/versions/latest/sdk/notifications/#managing-notification-categories-interactive-notifications
https://github.com/expo/expo-server-sdk-node
Thank you in advance for your answers ❤️
I'm not quite sure about the square image, but in order to handle redirects you can look at this documentation from expo: https://docs.expo.dev/push-notifications/receiving-notifications/.
You can then pass the data you need for your redirect (i.e. notification_type, relevant id etc) via the data property on your message (this will need to be done wherever the message is created, which from your question is from the node api):
messages.push({
to: pushToken,
body: 'This is a test notification',
data: { notification_type: 'something', id: 'something_else' },
});
It is then up to you to decide how to handle that message based on the extra data you have provided.
For example, taking the code provided in the link above as an example, you could have a handle function as follows:
_handleNotification = response => {
const data = response.notification.request.content;
if (data.type === "new_message") {
// navigate to MessageScreen with data.id as param
} else {
// do something else based on the type or...
}
};
I'm very new to liferay, I've created a page custom field using 'control panel > configuration > custom fields > page'. My goal is to retrieve the value from the page custom field and display the value in my custom portlet. One of the methods I've tried is using ExpandoValue/get-data API from the liferay json web service and this API is generated from localhost:8080/api/jsonws. Below is the generated javascript API:
Liferay.Service(
'/expandovalue/get-data',
{
companyId: themeDisplay.getCompanyId(),
className: 'com.liferay.portal.model.Page',
tableName: 'CUSTOM_FIELDS',
columnNames: 'pageDetail',
classPK: themeDisplay.getUserId()
},
function(obj) {
console.log(obj);
}
);
However, this api throws me an error: java.lang.NullPointerException. I'm thinking that this error occurs due to the permission given to the custom field. So, I've ticked View and Update permissions for Guest. But the issue persists.
My question is what triggered this error and how to fix it and is there any other solution I can use to retrieve the value from the page custom field?
Thanks in advance.
Edit
I had misunderstanding in assigning the attributes for the api and here is the new api as suggested by Olaf.
Liferay.Service(
'/expandovalue/get-data',
{
companyId: 20115,
className: 'com.liferay.portal.kernel.model.Layout',
tableName: 'CUSTOM_FIELDS',
columnName: 'details',
classPK: themeDisplay.getLayoutId()
},
function(obj) {
console.log(obj);
}
);
It works fine. However it only took the default value but not the value assign for that particular pages.
If memory serves me right, the stock remote API can't be used by unauthenticated users, but requires at least a logged in user (on top of the regular permissions of course).
You can test for this by accessing the API from logged in accounts with the same permissions. If it works there, then this is what you're running into.
However, when I interpret the call in your question correctly, the current user id would be the primary key for the custom field that you're looking at (looking at your classPK value). For a custom field on the page, I'd have expected a page id (layoutId in Liferay-API-terms). And while I'm seeing this, I notice com.liferay.portal.model.Page in your snippet. I've not seen that class, and pages can rather be found in com.liferay.portal.kernel.model.Layout (Assuming Liferay 7.1)
This makes me wonder what you're trying to achieve here - are you rather looking for a user-specific field (that would then be a custom field on the user) or really a page-specific field? Anyways - as this is an answer, not a comment, it might give enough hints to try out and come closer to a solution.
I am attempting to use the Wikipedia API to retrieve article titles and snippets of the article's text. But when I try to access those properties, I am getting the error "Cannot read property of undefined."
Here is my JSON response:
{
"batchcomplete": "",
"continue": {
"gsroffset": 10,
"continue": "gsroffset||"
},
"query": {
"pages": {
"13834": {
"pageid": 13834,
"ns": 0,
"title": "\"Hello, World!\" program",
"index": 6,
"extract": "<p>A <b>\"Hello, World!\" program</b> is a computer program that outputs or displays \"Hello, World!\" to a user. Being a very simple program in most programming languages, it is often used to illustrate the</p>..."
},
"6710844": {
"pageid": 6710844,
"ns": 0,
"title": "Hello",
"index": 1,
"extract": "<p><i><b>Hello</b></i> is a salutation or greeting in the English language. It is first attested in writing from 1826.</p>..."
},
"1122016": {
"pageid": 1122016,
"ns": 0,
"title": "Hello! (magazine)",
"index": 7,
"extract": "<p><i><b>Hello</b></i> (stylised as <i><b>HELLO!</b></i>) is a weekly magazine specialising in celebrity news and human-interest stories, published in the United Kingdom since 1988. It is the United Kingdom</p>..."
}
}
}
}
I have tried a couple different ways of writing the code. For example, this works (logs the pages as an object in the console):
console.log(response.query.pages);
But this returns the error I wrote above ("Cannot read property of undefined"):
console.log(response.query.pages[0].title);
Any suggestions on how to access the attributes "title" and "extract" would be appreciated. Thanks.
That's because pages is not an array; it's an object where the keys are the ids. So you need to do:
console.log(response.query.pages[1122016].title);
This will work. If you want the "first" page, for instance, then
let pages = response.query.pages;
console.log(pages[Object.keys(pages)[0]].title);
Note that I'm not sure if the order of the keys in JS objects is guaranteed.
If you want to iterate over the pages, do
let pages = response.query.pages;
Object.keys(pages).forEach(id => {
let page = pages[id];
console.log(page.title, page.foo);
});
Special Case: Working with Asynchronous Calls
Howdy fellow devs,
If you're checking out this thread because you're working with a framework like React, or some other framework that has you using a development server (e.g. using npm start or something similar), your dev server may be crashing when you try to do something like console.log(response.foo.bar) before it refreshes on data reload.
Specifically, my dev server was crashing with the Cannot read property 'bar' of undefined type message, and I was like, "what the heck is going on here!?". Solution: put that baby in a try/catch block:
try {
console.log(rate['bar'].rate)
} catch (error) {
console.log(error)
}
Why? If your App has a default state (even an empty array, for example), then it tries to console.log the response before the data has been received from the remote source, it will successfully log your empty state, but if you try to reference parts of the object you're expecting to receive from the remote source in your console.log or whatever else, the dev server will be trying to reference something not there on initial load and crash before it has a chance to reference it when it's actually received from the remote source via API or whatever.
Hope this helps someone!
I'm not sure which language you're using to parse the JSON (looks like Javascript from console.log?) but the issue is that query.pages is a dictionary, not an array, so it can't be iterated by index, only by key.
So you want something like (pseudocode):
for (key in response.query.keys)
{
console.log(response.query[key].title);
}
I'm able to use GMail's Users.threads.list API call to retrieve a list of the threads. I'd like to also grab the labels belonging to each message in the thread.
On the official documentation / live example for this method, there is an area called fields where the user can specify the optional fields they wish to pull in. They even provide a little UI tool call 'fields editor' to help you select and properly format the fields for inclusion in the REST query:
Which results in the following, valid, generated fields parameter values:
nextPageToken,resultSizeEstimate,threads(historyId,id,messages/labelIds)
The final request looks like this:
GET https://www.googleapis.com/gmail/v1/users/me/threads?includeSpamTrash=true&fields=nextPageToken%2CresultSizeEstimate%2Cthreads&key={YOUR_API_KEY}
After authenticating with OAuth2, I get back a list of threads[], but none of them include the expected messages[] array nested within them! I know the field mask is valid because GMail API errors out when you request a field the method doesn't support with a standard HTTP 400 and a pretty printed error message. But in this case, all I get back is an object that contains an array labeled "threads", where each thread object only has the following fields:
id
snippet
historyId
But no messages array. Stranger yet, even when I remove the fields custom filter parameter, I still get back these same results. Am I missing something obvious here?
You have to list the id of the threads first, and then make a separate request to get the thread and fields in the messages you want. The API Explorer allows you to select additional fields when listing for some reason.
1. List ids
Request
GET https://www.googleapis.com/gmail/v1/users/me/threads?access_token={access_token}
Response
{
"threads": [
{
"id": "1570f8c16a1084de",
"snippet": "Foo bar...",
"historyId": "1234"
}, ...
],
"resultSizeEstimate": 100
}
2. Get the thread
Request
GET https://www.googleapis.com/gmail/v1/users/me/threads/1570f8c16a1084de?access_token={access_token}
Response
{
"id": "1570f8c16a1084de",
"historyId": "1234",
"messages": [
{
"id": "1570f8c16a1084de",
"threadId": "1570f8c16a1084de",
"labelIds": [
"INBOX",
"IMPORTANT",
"CATEGORY_FORUMS"
], ...
}
}
If you don't want to list threads and then get them all separately, you could use batch requests to bring it down to 2 requests instead.
I am working on Facebook application (JS sdk), In this app user can post like/comment on a photo. For this activity, It is showing a like button at bottom of photo. But if user already liked particular photo then we don't show like button there. For this we need to know weather user already liked the photo or not. It is possible to know this using FQL
SELECT object_id,like_info,comment_info FROM photo WHERE object_id=343907262480651
And it returns a boolean flag data["like_info"]["user_likes"]
I am migrating my code from graph api v1.0 to v2.2. So FQL will is longer available.
I want solution in graph API 2.2 similar to user_likes flag. I searched a lot for this, but not getting what exactly i want. Is there any alternative way to achieve this?
Thanks.
To get the likes for an object, you make call to
/{object-id}/likes
If you want the total number as a field, you need to set the field summary=true
I'm trying to accomplish the exact thing. So far, I couldn't find any end point that will readily tell you whether the user has already liked the post or not. But one work around is to call the /{object-id}/likes end point that will return you something like below:
{
"data": [
{
"id": "808004209267865",
"name": "Kailey Nicole"
},
{
"id": "10204107012455593",
"name": "Brenda S. Coffelt"
}
],
"paging": {
"cursors": {
"before": "OTU1NzQ4ODQxMTIyNDEz",
"after": "MTAyMDQxMDcwMTI0NTU1OTM="
},
"next": "https://graph.facebook.com/v2.3/10151929326420059/likes?pretty=0&limit=25&after=MTAyMDQxMDcwMTI0NTU1OTM="
}
}
You can then easily look for the user id in this JSON array. If it exists that means the user likes the page otherwise not. However keep in mind that there can be pagination (in case of lot of likes), so you'd really have to keep using the next URL to exhaust all likes data.