I have create a Node application that uses the Twit(twitter api) to allow my ionic/Angular Application to post a tweet on twitter, however this problem that I have is that i get a 404 error message when I set the REST method to Post, it seems to work with a GET method.
However I do not know how I can dynamically change the Data in my node application from my Ionic Application.
I want to change the User's information and the Message that is being sent, but I do not know where to start. if anyone can guide me that will be appriecated.
this is my Node server.js file
const express = require('express');
const Twitter = require('twit');
const app = express();
const client = new Twitter({
consumer_key: '...',
consumer_secret: '...',
access_token: '...',
access_token_secret: '...',
});
app.use(require('cors')());
app.use(require('body-parser').json());
app.post('/post_tweet', (req, res) => {
tweet = {status:"Random"};
client
.post(`statuses/update`, tweet)
.then(timeline => {
console.log(timeline);
res.send(timeline);
})
.catch(error => {
res.send(error);
});
});
app.listen(3000, () => console.log('Server running'));
this is my twitter service in my Ionic application
import { Injectable } from '#angular/core';
import { HttpClient } from '#angular/common/http';
import { map } from 'rxjs/operators';
#Injectable({
providedIn: 'root'
})
export class TwitterserviceService {
api_url = 'http://localhost:3000';
constructor(private http: HttpClient) { }
tweet(tweetdata: string) {
return this.http.get<any>(`${this.api_url}/post_tweet`)
.pipe(map(tweet => {
alert("tweet posted")
return tweet;
}));
}
}
and this is the method that I use to send a Post, however the message "this works" doesent post instead the default message in the Node application is sent "random"
sendTweet() {
this.api.tweet('this works')
.pipe(first())
.subscribe(
data => {
console.log('yes')
},
error => {
'failed'
});
}
Your service should do a POST, not a GET. And a POST must have a body.
tweet(tweetdata: string) {
return this.http.post<any>(`${this.api_url}/post_tweet`, { tweetdata })
}
note that you will have to handle this body in the express route and probably do something with this tweetdata attribute.
Alright I have found the answer and it was actually quite simple
here it the link to the resource that i am using => https://code.tutsplus.com/tutorials/connect-to-the-twitter-api-in-an-angular-6-app--cms-32315
this is my node js code
const express = require('express');
const Twitter = require('twit');
const app = express();
const client = new Twitter({
consumer_key: '...',
consumer_secret: '...',
access_token: '...',
access_token_secret: '...',
});
app.use(require('cors')());
app.use(require('body-parser').json());
app.post('/post_tweet', (req, res) => {
tweet = req.body;
client
.post(`statuses/update`, tweet)
.then(tweeting => {
console.log(tweeting);
res.send(tweeting);
})
.catch(error => {
res.send(error);
});
});
app.listen(3000, () => console.log('Server running'));
and here it the code that I have in my Ionic/Angular Project
api_url = 'http://localhost:3000';
tweet(tweetdata: string) {
return this.http.post<any>(`${this.api_url}/post_tweet/`, {status: tweetdata})
.pipe(map(tweet => {
alert("tweet posted")
return tweet;
}));
}
sendTweet() {
this.tweet('This is app code')
.pipe(first())
.subscribe(
data => {
console.log('yes')
},
error => {
'failed'
});
}
hope this helps someone.
Related
I had a question that doesn't seem to be answered anywhere.
I am running tests from within my Express.js api. I set up a page that has a button and a field to enter a keyword intended to be used during a testcafe test. My endpoint I set up is /testcafe. But after sending a post request to /testcafe, there is a long delay while test runs and so my question is what is the best next step besides hanging?
Also, can my post request body, which contains the keyword, be directly used in a test like this? Keep in mind it's this pattern:
frontend -> POST request -> Express server -> /testcafe endpoint - test
My problem is after it reaches test, I currently have it attempting to call fetch from within the request logger. Is this right?
import { ClientFunction, Selector } from 'testcafe';
import { RequestLogger, RequestHook } from 'testcafe';
import zlib from 'zlib';
import fetch from 'isomorphic-unfetch';
const url = 'https://www.mysitetesturl.com/page';
class MyRequestHook extends RequestHook {
constructor (requestFilterRules, responseEventConfigureOpts) {
super(requestFilterRules, responseEventConfigureOpts);
}
onRequest (e) {
console.log('in onRequest!')
console.log('========================')
console.log('Request Body')
let buf = e._requestContext.reqBody
console.log(buf.toLocaleString())
}
onResponse (e) {
let buf = Buffer(e.body)
let unzippedBody = Buffer(zlib.gunzipSync(buf))
let payload = unzippedBody.toLocaleString()
fetch('http://myapiipaddress/api/testcafe',
method: 'PUT',
body: JSON.stringify(payload)
)
.then((err, doc) => {
if(err) {
console.log(err)
} else {
console.log(doc)
}
})
}
}
const myRequestHook = new MyRequestHook({
url: url,
method:'get'},
{
includeHeaders: true,
includeBody: true
}
);
fetch('http://myapiipaddress/api/testcafe',
method: 'GET'
)
.then((err, doc) => {
if(err) {
console.log(err)
} else {
fixture`myfixture`
.page(doc.url)
.requestHooks(myRequestHook);
test(`mytest`, async t => {
const inputField = Selector('input');
await t
await t
.wait(5000)
.typeText(inputField, doc.text)
.wait(5000)
}
);
}
})
According to your scheme, you need to organize your code in a different way:
const createTestCafe = require('testcafe');
....
// Choose the necessary body parser for express application
// https://github.com/expressjs/body-parser
app.use(bodyParser.urlencoded({ extended: true }));
...
app.post('/', function (req, res) {
createTestCafe('localhost', 1337, 1338, void 0, true)
.then(testcafe => {
const runner = testcafe.createRunner();
return runner
.src('/tests')
.browsers('chrome')
.run();
})
.then(failedCount => {
testcafe.close();
res.end();
});
})
I have a button that lauches a fetch to my API that uses KOA and JWT. The javascript for the fetch initiated on click is:
<script>
function loginButton(user, pass) {
fetch('http://localhost:5454/api/login', {
method: "post",
headers: {
'Content-Type': "application/json"
},
body: JSON.stringify({
username: user,
password: pass
})
})
.then( (response) => {
console.log("Success")
})
.catch(e => console.log(e));
}
</script>
The code for my Authentication is:
router.post(`${BASE_URL}/login`, async (ctx) => {
const reqUsername = ctx.request.body.username
const reqPassword = ctx.request.body.password
const unauthorized = (ctx) => {
ctx.status = 401
ctx.body = {
error: 'Invalid username or password'
}
}
let attemptingUser
try {
attemptingUser = await Employee.findOne({ where: { username: reqUsername }})
if (attemptingUser != null && attemptingUser.password === reqPassword) {
ctx.status = 200
ctx.body = {
username: attemptingUser.username,
given_name: attemptingUser.given_name,
role: attemptingUser.role,
created_at: attemptingUser.createdAt,
updated_at: attemptingUser.updatedAt,
}
const token = jwt.sign({ username: attemptingUser.username, role: attemptingUser.role }, SECRET)
ctx.set("X-Auth", token)
} else {
unauthorized(ctx)
}
} catch(err) {
console.error(err)
console.error(`Failed to find username: ${reqUsername}`)
unauthorized(ctx)
}
})
The code for my KOA initiation is:
require('dotenv').config()
const Koa = require('koa')
const Router = require('koa-router')
const bodyParser = require('koa-bodyparser')
const baseRoutes = require('./routes')
const cors = require('#koa/cors');
const PORT = process.env.PORT || 8080
const app = new Koa()
app.use(bodyParser())
app.use(baseRoutes.routes())
app.use(cors());
app.listen(PORT, () => {
console.log(`Server listening on ${PORT}`)
})
Im using Port 8080 for my http-server and port 5454 for my npm server. I am getting a Failed to Fetch in the catch of the Fetch, as well as a CORS error related to not having a Access-Control-Allow-Origin header in the response header. I've tried a couple things and am ready to have a new set of eyes look at it, any tips?
Edit: I am successfully receiving the token in the X-Auth header, but for some reason it’s still throwing errors and I’d like to get them resolved before it spirals out of control.
I+m playing with the Chatkit API, and when running a React app in my local machine everything seems to work fine, but when I pushed it to Heroku, every time it tries to do a POST request through the server, it gives Failed to load resource: net::ERR_CONNECTION_REFUSED and index.js:1375 error TypeError: Failed to fetch
This is my server.js
const express = require('express')
const bodyParser = require('body-parser')
const cors = require('cors')
const Chatkit = require('#pusher/chatkit-server')
const app = express()
const chatkit = new Chatkit.default({
instanceLocator: I HAVE MY INSTANCE LOCATOR HERE,
key: I HAVE MY KEY HERE,
})
app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
app.use(cors())
app.post('/users', (req, res) => {
const { username } = req.body
chatkit
.createUser({
id: username,
name: username
})
.then(() => res.sendStatus(201))
.catch(error => {
if (error.error === 'services/chatkit/user_already_exists') {
res.sendStatus(200)
} else {
res.status(error.status).json(error)
}
})
})
app.post('/authenticate', (req, res) => {
const authData = chatkit.authenticate({ userId: req.query.user_id })
res.status(authData.status).send(authData.body)
})
const PORT = 3001
app.listen(PORT, err => {
if (err) {
console.error(err)
} else {
console.log(`Running on port ${PORT}`)
}
})
And then this is my App.js
import React, { Component } from 'react'
import UsernameForm from './components/UsernameForm'
import ChatScreen from './ChatScreen'
class App extends Component {
constructor() {
super()
this.state = {
currentUsername: '',
currentScreen: 'WhatIsYourUsernameScreen'
}
this.onUsernameSubmitted = this.onUsernameSubmitted.bind(this)
}
onUsernameSubmitted(username) {
fetch('http://localhost:3001/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ username }),
})
.then(response => {
this.setState({
currentUsername: username,
currentScreen: 'ChatScreen'
})
})
.catch(error => console.error('error', error))
}
render() {
if (this.state.currentScreen === 'WhatIsYourUsernameScreen') {
return <UsernameForm onSubmit={this.onUsernameSubmitted} />
}
if (this.state.currentScreen === 'ChatScreen') {
return <ChatScreen currentUsername={this.state.currentUsername} />
}
}
}
export default App
I believe that it's at this time that it breaks
return <UsernameForm onSubmit={this.onUsernameSubmitted} />
When submitting it is expected to make a POST request to create a new user, and React to load the new component, but it just stays in the UsernameForm component, and in the console I can see these errors:
Failed to load resource: net::ERR_CONNECTION_REFUSED
index.js:1375 error TypeError: Failed to fetch
Probably the issue is the localhost in the endpoint at onUsernameSubmitted. We need more details about how your application is deployed and how the communication between server and spa is designed. If you have an Nginx you can set the redirect there.
I see three potential reasons of the error:
Database has to be well deployed and db:migrate triggered to define the db schema.
If 1) is fulfilled, then make sure whether your graphql path points to server url my-app.herokuapp.com not to localhost:<port>, The easiest way to check that is via browser/devtools/network query.
(optional) I use ApolloClient and my rule process?.env?.NODE_ENV ? 'prod_url' : 'dev_url' didn't work because of missing vars definitions in webpack:
new DefinePlugin({
'process.env': {
NODE_ENV: JSON.stringify(process.env.NODE_ENV),
},
}),```
I have a problem, when I post my form, i can't get what is in my post in my API.
this is my post with axios in react :
onSubmit = () => {
let data = {
nickname: this.state.nickname,
password: this.state.password
}
axios.post("/api/user/login", { data })
.then(res => {
console.log("res from api is => ", res.data);
})
}
and this is in my API :
import koaBody from "koa-body";
const app = new koa();
const router = new Router();
app.use(router.routes());
app.use(koaBody());
router.post("/api/user/login", async(ctx) => {
console.log("body is => ", ctx.request.body);
ctx.body = "ok";
});
the problem is ctx.request.body is always undefined...
Can you tell me why ?
I tried with router.get and I have no problem, it works fine.
You need to load the body parser before the router, otherwise the router will get to handle the requests before the body contents are parsed:
app.use(koaBody());
app.use(router.routes());
I'm trying to stream the timeline of another user.
I've set up an app and got all the creds, but I keep getting a 401. What am I doing wrong?
import Twitter from 'twitter';
import socketIO from 'socket.io';
import streamHandler from './../util/streamHandler';
import http from 'http';
export default function(app, serverConfig) {
const server = http.createServer(app);
const io = socketIO(server);
const twit = new Twitter(serverConfig.twitter);
twit.stream('statuses/filter', {
follow: ['76633197'],
}, (stream) => {
stream.on('data', (tweet) => {
console.log('data');
console.log(tweet.text);
});
stream.on('error', (error) => {
console.log(error);
});
});
return server;
}
serverConfig.twitter looks like:
{
consumer_key: <redacted>,
consumer_secret: <redacted>,
access_token_key: <redacted>,
access_token_secret: <redacted>
}
UPDATE: This only happens when I follow. If I pass {track: 'javascript'} as the parameter it works fine...