i have a Rails API
Ex. example.com/v1/portfolio/{{ id }}
and i'm using AngularJS ngResource to handle the data with get.
myAppServices.factory('Portfolio', ['$resource', function($resource){
return $resource('api/v1/portfolios/:id/', { id:'#id'}, {
query: {
method:'GET',
params:{id:'#id'},
isArray:true
}
});
}]);
How can i handle the Not found 404 Error if the API does not have an Entry
Ex. example.com/v1/portfolio/blabla
i mean how can i make it 404 like when u enter http://www.google.com/sdfa check the network status code you'll find it 404.
For more information am using Prerender.io service to Render the website for Search Engines.
You can use $promise like this:
var resource = $resource('api/v1/portfolios/:id/');
resource.get({id: 123}).$promise.then(function(todo) {
// success
}, function(errResponse) {
// handle 404 here
});
You should use the prerender-status-code meta tag to return a 404 to the crawler. The documentation is here: https://prerender.io/documentation/best-practices
Basically, just add to the of the page if the page should return a 404 to crawlers. Prerender.io will detect that status code and return that to the crawler instead of a 200.
Feel free to send an email to support#prerender.io if you have any other questions about that. We're happy to help!
Related
I'm working with an API, which after filling out the log in form on their website, redirects back to our website, with a unique code at the end of the URL.
Example URL after redirect:
https://www.mywebsite.com/?code=12431453154545
I have been unable to find a way of viewing this URL in Postman.
Ideally I need to be able to work with that URL to extract the code and store it as a variable.
Any help will be muchly appreciated. I've been trying this all day :( .
When you turn off following redirects in Postman settings, you will be able to inspect 3xx HTTP response which will contain Location header with the URL you want to read.
const url = require("url");
var location = pm.response.headers.get("location");
if (typeof location !== typeof undefined) {
var redirectUrl = url.parse(location, true);
query = redirectUrl.query;
if ("code" in query) {
pm.globals.set("code", query.code);
console.log(pm.globals.get("code"));
}
}
Note that this solution will not work when multiple subsequent redirects happen as you will be inspecting only the first 3xx response. You could solve this by following redirects manually and sending your own requests from Postman script as described in Postman manual.
I'm trying to integrate Medium blogging into an app by showing some cards with posts images and links to the original Medium publication.
From Medium API docs I can see how to retrieve publications and create posts, but it doesn't mention retrieving posts. Is retrieving posts/stories for a user currently possible using the Medium's API?
The API is write-only and is not intended to retrieve posts (Medium staff told me)
You can simply use the RSS feed as such:
https://medium.com/feed/#your_profile
You can simply get the RSS feed via GET, then if you need it in JSON format just use a NPM module like rss-to-json and you're good to go.
Edit:
It is possible to make a request to the following URL and you will get the response. Unfortunately, the response is in RSS format which would require some parsing to JSON if needed.
https://medium.com/feed/#yourhandle
⚠️ The following approach is not applicable anymore as it is behind Cloudflare's DDoS protection.
If you planning to get it from the Client-side using JavaScript or jQuery or Angular, etc. then you need to build an API gateway or web service that serves your feed. In the case of PHP, RoR, or any server-side that should not be the case.
You can get it directly in JSON format as given beneath:
https://medium.com/#yourhandle/latest?format=json
In my case, I made a simple web service in the express app and host it over Heroku. React App hits the API exposed over Heroku and gets the data.
const MEDIUM_URL = "https://medium.com/#yourhandle/latest?format=json";
router.get("/posts", (req, res, next) => {
request.get(MEDIUM_URL, (err, apiRes, body) => {
if (!err && apiRes.statusCode === 200) {
let i = body.indexOf("{");
const data = body.substr(i);
res.send(data);
} else {
res.sendStatus(500).json(err);
}
});
});
Nowadays this URL:
https://medium.com/#username/latest?format=json
sits behind Cloudflare's DDoS protection service so instead of consistently being served your feed in JSON format, you will usually receive instead an HTML which is suppose to render a website to complete a reCAPTCHA and leaving you with no data from an API request.
And the following:
https://medium.com/feed/#username
has a limit of the latest 10 posts.
I'd suggest this free Cloudflare Worker that I made for this purpose. It works as a facade so you don't have to worry about neither how the posts are obtained from source, reCAPTCHAs or pagination.
Full article about it.
Live example. To fetch the following items add the query param ?next= with the value of the JSON field next which the API provides.
const MdFetch = async (name) => {
const res = await fetch(
`https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/${name}`
);
return await res.json();
};
const data = await MdFetch('#chawki726');
To get your posts as JSON objects
you can replace your user name instead of #USERNAME.
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/#USERNAME
With that REST method you would do this: GET https://api.medium.com/v1/users/{{userId}}/publications and this would return the title, image, and the item's URL.
Further details: https://github.com/Medium/medium-api-docs#32-publications .
You can also add "?format=json" to the end of any URL on Medium and get useful data back.
Use this url, this url will give json format of posts
Replace studytact with your feed name
https://api.rss2json.com/v1/api.json?rss_url=https://medium.com/feed/studytact
I have built a basic function using AWS Lambda and AWS API Gateway if anyone is interested. A detailed explanation is found on this blog post here and the repository for the the Lambda function built with Node.js is found here on Github. Hopefully someone here finds it useful.
(Updating the JS Fiddle and the Clay function that explains it as we updated the function syntax to be cleaner)
I wrapped the Github package #mark-fasel was mentioning below into a Clay microservice that enables you to do exactly this:
Simplified Return Format: https://www.clay.run/services/nicoslepicos/medium-get-user-posts-new/code
I put together a little fiddle, since a user was asking how to use the endpoint in HTML to get the titles for their last 3 posts:
https://jsfiddle.net/h405m3ma/3/
You can call the API as:
curl -i -H "Content-Type: application/json" -X POST -d '{"username":"nicolaerusan"}' https://clay.run/services/nicoslepicos/medium-get-users-posts-simple
You can also use it easily in your node code using the clay-client npm package and just write:
Clay.run('nicoslepicos/medium-get-user-posts-new', {"profile":"profileValue"})
.then((result) => {
// Do what you want with returned result
console.log(result);
})
.catch((error) => {
console.log(error);
});
Hope that's helpful!
Check this One you will get all info about your own post........
mediumController.getBlogs = (req, res) => {
parser('https://medium.com/feed/#profileName', function (err, rss) {
if (err) {
console.log(err);
}
var stories = [];
for (var i = rss.length - 1; i >= 0; i--) {
var new_story = {};
new_story.title = rss[i].title;
new_story.description = rss[i].description;
new_story.date = rss[i].date;
new_story.link = rss[i].link;
new_story.author = rss[i].author;
new_story.comments = rss[i].comments;
stories.push(new_story);
}
console.log('stories:');
console.dir(stories);
res.json(200, {
Data: stories
})
});
}
I have created a custom REST API to retrieve the stats of a given post on Medium, all you need is to send a GET request to my custom API and you will retrieve the stats as a Json abject as follows:
Request :
curl https://endpoint/api/stats?story_url=THE_URL_OF_THE_MEDIUM_STORY
Response:
{
"claps": 78,
"comments": 1
}
The API responds within a reasonable response time (< 2 sec), you can find more about it in the following Medium article.
I am new to backbone and been trying to pull off an authentication but in vain. Please help over here;
My view looks like this;
mama.Views.UserSessionsIndex = Backbone.View.extend({
template: JST['user_sessions/index'],
render: function() {
this.$el.html( this.template );
return this;
},
events: {
"click #sign_in_button": "signIn"
},
signIn: function(event) {
var userSession = new Skymama.Models.UserSession;
userSession.set({email: $('#email_address').val(), password: $('#password').val()});
userSession.save({
success: function(model, response) {
alert("response");
},
error: function(model, response){
alert("response");
}
});
}
});
However, i get this response 401 Unauthorized for an authorised error. How can i handle these response, log in the client and redirect them.
Thank you
If you finally expect a redirect, don't use Backbone model because JSON response won't get you redirected.
Instead, within this Backbone view, display traditional Devise form and send HTML request.
You need a RESTful way to login from Backbone to Rails (Devise).
Tutorial 1: http://joshhuckabee.com/integrating-devise-backbonejs
Tutorial 2: http://chasseurmic.github.io/chasseurmic/blog/2013/02/13/restful-api-authentication/
Prepare the RESTful config/controller. After, using a POST call you can authenticate with Rails.
I'm building an app which is architected as a Rails server app providing RESTful api's to the client. The Rails server uses RABL. The client is an Angular JS client performing standard $http calls (gets, puts, etc).
Occasionally my Rails server will produce an error (let's say validation error attached to the object) or even no error in which case I would want to display something to the user - either the errror e.g., "The record did not save because..." or "The record was updated successfully".
I'm trying to map out a pattern on both the Rails side and the Angular/client side to handle this.
As for Rails:
I can certainly pass back a node in each of my RABL files to contain error arrays
I can also return different RABL by checking in the controller before returning
Most suggest using http codes (which makes sense) as per here (although there doesn't seem to be a consistent usages of the codes for something like a validation error).
As for Angular:
I suppose I can write a response interceptor but not sure how that would fully get flushed out.
I guess I'm hoping that I don't have to reinvent the wheel here and someone can point me to a pattern that's currently used and suggested (and localized).
I went ahead and implemented what I thought needed to be done. Thanks for digger69 for some help with this.
On the Rails side, I went with using an http status code. As per here I agreed with using a 400 http status code for error validation.
In my controllers I now have something like the following:
def create
my_obj = MyObj.build_with_params(params)
if my_obj.save
respond_with(my_obj) # regular RABL response
else
respond_with_errors(my_obj.errors)
end
end
In my application_controller.rb I defined a common method respond_with_errors
# respond back to the client an http 400 status plus the errors array
def respond_with_errors(errors)
render :json => {:errors => errors}, :status => :bad_request
end
Note that the :bad_request symbol is already defined for Rails as per here
On the client side I needed to intercept http calls (not only for validation but for authentication failures too (and probably more). Here is an example of my code in Angular (thanks to this post for the help with that):
var interceptor = ['$rootScope', '$q', function (scope, $q) {
function success(response) {
return response;
}
function error(response) {
var status = response.status;
if (status == 401) { // unauthorized - redirect to login again
window.location = "/";
} else if (status == 400) { // validation error display errors
alert(JSON.stringify(response.data.errors)); // here really we need to format this but just showing as alert.
} else {
// otherwise reject other status codes
return $q.reject(response);
}
}
return function (promise) {
return promise.then(success, error);
}
}];
$httpProvider.responseInterceptors.push(interceptor);
I now can be consistent with my rails code and deal with success returns from http calls on the client. I'm sure I have some more to do, but I think this gives a localized solution.
Use an HTTP response interceptor. I am currently using that successfully in an application.
http://docs.angularjs.org/api/ng.$http
From the documentation:
$provide.factory('myHttpInterceptor', function($q, dependency1, dependency2) {
return function(promise) {
return promise.then(function(response) {
// do something on success
}, function(response) {
// do something on error
if (canRecover(response)) {
return responseOrNewPromise
}
return $q.reject(response);
});
}
});
$httpProvider.responseInterceptors.push('myHttpInterceptor');
In my case I created a feedback service, which displays either success or error messages globally. An other option would be to broadcast the responses on the rootscope.
I got some code by doing search which is doing a lot for me in showing the my tweets in tableview,till now fine. I want to add one more functionality to it that user can post the message from the sameapp.
So I just modified the code as per. While I hit the request I got result status as successful but message is not posting to my wall. I have all keys and getting access token as well.
var client = Twitter({
consumerKey: "have Key ",
consumerSecret: "have Key",
accessTokenKey: accessTokenKey,
accessTokenSecret: accessTokenSecret
});
client.request("1/statuses/update.json", {status:'TEST'}, 'GET', function(e) {
if (e.success) {alert(e.success);
} else {
alert(e.error);
}
Updated: I have go through the Twitter Dev API
This is the URL http://api.twitter.com/1/statuses/update.format with required parameter "status". What am I doing wrong?
You are sending GET request to update status whereas twitter api needs it to be a POST request.
Try something like
client.request( "1/statuses/update.json", {status:'TEST'}, 'POST', function(e) {
if (e.success)
{
alert(e.success);
} else {
alert(e.error);
}
Check out this application: https://github.com/appcelerator-titans/tweetanium
From what I understand this is a fully working example of a twitter app created using Titanium Mobile. Perhaps you can follow the logic in here and see where you need to adjust.