5

I'm trying to use AJAX calls to send data back and forth between my Javascript frontend for my chrome extension and the Flask API where I plan to use my Machine Learning code.

content.js

console.log("Application GO");

function colorChanger() {
  let tweets = document.querySelectorAll("article");
  tweets.forEach(function (tweet) {
    $(document).ready(function () {
    $.ajax({
          type: "POST",
          contentType: "application/json;charset=utf-8",
          url: "/_api_call",
          traditional: "true",
          data: JSON.stringify({tweet}),
          dataType: "json"
          });
  });

    tweet.setAttribute("style", "background-color: red;");
  });
}

let timer = setInterval(colorChanger, 2000);

flask code

from flask import Flask, flash, request, redirect, url_for
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route('/_api_call', methods=['GET'])
def fake_news_detector():
    data = request.get_json()
    with open('temp.txt', 'w') as f:
        f.write(data)
    return data

Error

Uncaught ReferenceError: $ is not defined
content.js:11 (anonymous function) // which points to line -  $(document).ready(function () {

I'm new to both Javascript and Flask. Any help would be really helpful. Thanks a lot !

Tony Stark
  • 117
  • 7
  • What specifically is the issue (what is the current behavior vs expected)? Do you get errors? Have you used the browser developer tools and/or a traffic debugging tools such as Fiddler to watch the call and observe what you are sending and where? Have you read up on asynchronous calls in javascript? – scrappedcola Dec 16 '20 at 16:18
  • if you get error message when you run it then show it in question (not in comment) as text (not image). Don't expect that we will run code to see problems. You have to all describe in question. – furas Dec 16 '20 at 16:50
  • in `$.ajax()` you only send data to Flask but you don't execute function which will get result from Flask. You need `$.ajax(..., success: function)` – furas Dec 16 '20 at 16:51
  • Extremely sorry. I have included the error script. Do have a look at it now. Thanks a lot. – Tony Stark Dec 16 '20 at 17:02
  • What is `JSON.stringify({temp})`? You never define a variable of the name `temp` anywhere. – Tomalak Dec 16 '20 at 17:29
  • I've edited it. – Tony Stark Dec 16 '20 at 17:44
  • @TonyStark Did you include jQuery before this script is run? https://stackoverflow.com/questions/2194992/jquery-is-not-defined – scrappedcola Dec 16 '20 at 17:46
  • No @scrappedcola, I didn't include it. What code shall I add there ? – Tony Stark Dec 16 '20 at 17:48
  • I see you've written `{tweet}` now. `tweet` is a DOM element list. What exactly do you expect does `{tweet}` do? Have you this checked that this actually produces the object you want to send? Because I would be *very* surprised if it did. – Tomalak Dec 16 '20 at 17:53
  • I'm currently just trying to send the tweet as a whole. I'd be modifying it later. The tweet just holds the DOM of the selected tweet in twitter. For now I'd like to complete a connection between the frontend and the Flask API, and then I can send whatever data I want and also include my ML code in Flask. – Tony Stark Dec 16 '20 at 17:58
  • @TonyStark `$.ajax` is part of the jQuery framework and not vanilla JS. To use you need to include it in your code, like any other 3rd party library. Start out with https://learn.jquery.com/about-jquery/how-jquery-works/. – scrappedcola Dec 16 '20 at 20:12
  • HI, add jquery cdn i.e : `` – Swati Dec 20 '20 at 11:43
  • Thanks @Swati, but isn't that used for including jquery in html. I don't think I can use it in a javascript code. – Tony Stark Dec 20 '20 at 11:45
  • You need to include this else jquery code will throw above error . Put that line at top inside `content.js` file – Swati Dec 20 '20 at 11:47

2 Answers2

1

$(document).ready and $.ajax requires jQuery

fetch and window.addEventListener works in almost all latest browsers

$(document).ready => window.addEventListener('DOMContentLoaded', function(evt) {})

$.ajax => fetch

Note: Calling $(document).ready again and again inside loop for each tweet is not a good option it will run a bunch of code again and again instead setInterval can be called once after document loading completes.

content.js

async function Request(url = '', data = {}, method = 'POST') {
  // Default options are marked with *
  const response = await fetch(url, {
    method: method, // *GET, POST, PUT, DELETE, etc.
    mode: 'cors', // no-cors, *cors, same-origin
    cache: 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
    credentials: 'same-origin', // include, *same-origin, omit
    headers: {
      'Content-Type': "application/json;charset=utf-8",
      // 'Content-Type': 'application/x-www-form-urlencoded',
    },
    redirect: 'follow', // manual, *follow, error
    referrerPolicy: 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
    body: JSON.stringify(data) // body data type must match "Content-Type" header
  });
  return response.json(); // parses JSON response into native JavaScript objects
}

console.log("Application GO");

function colorChanger() {
  let tweets = document.querySelectorAll("article");

  tweets.forEach(function (tweet) {
    let response = Request("/_api_call", {tweet});
    tweet.setAttribute("style", "background-color: red;");
  });
}

window.addEventListener('DOMContentLoaded', (event) => {
    console.log('Called once after document load');
    let timer = setInterval(colorChanger, 2000);
});
Chandan
  • 11,465
  • 1
  • 6
  • 25
  • Thanks. Should I make modifications in the flask code too ? – Tony Stark Dec 20 '20 at 12:28
  • @TonyStark There are 2 changes: you can change `return data` to `return jsonify(data)` if you are want to return json from backend and you are handling only `GET` method in `_api_call` route which should be either both `GET` & `POST` or just `POST` – Chandan Dec 20 '20 at 13:17
  • Thanks again. But the chrome extension still doesn't work. Can you have a look at the entire code [here](https://drive.google.com/file/d/14_guO5PoV-IB0vV1CycXl2cFxRIL_xHJ/view?usp=sharing) if your free. – Tony Stark Dec 20 '20 at 13:57
  • @TonyStark check [this](https://wetransfer.com/downloads/9a915e9f0a338f56a3583d6b712fc4ac20201220150810/da00fb) i have include readme for information. – Chandan Dec 20 '20 at 15:12
  • @TonyStark sorry i did'nt read chrome extension word in you question. – Chandan Dec 20 '20 at 15:15
  • It's fine. I should have included it in the heading. Anyway I could use this code for a chrome extension ? – Tony Stark Dec 20 '20 at 17:09
  • @TonyStark i forget to include one information you have to properly indent python code if you are using space then you have to stick with spaces and if you are using tabs then you have to use tabs for indentation in one line you used tabs and in all file you used space. – Chandan Dec 20 '20 at 17:44
  • @TonyStark i created a temp html page for extension and use that to test it – Chandan Dec 20 '20 at 17:46
  • Yes, I got it. I'll stick with tabs and I'll check the temp html page too. Thanks a lot :) – Tony Stark Dec 20 '20 at 17:49
  • The code doesn't send information back and forth. I seem to get this [error](https://drive.google.com/file/d/1KcIYb-LpMpnFUyGZh56FOPa1Q8mLsJWj/view?usp=sharing) – Tony Stark Dec 21 '20 at 12:13
  • @TonyStark did you started flask server – Chandan Dec 21 '20 at 13:29
  • Yes, I did. It still gives the same error. – Tony Stark Dec 22 '20 at 17:46
0

First of all you don't have jQuery installed so you can't access $ and your error

Uncaught ReferenceError: $ is not defined

is saying that. you should include jQuery in your js code in order to use $ and call ajax. just follow @scrappedcola comment and follow the instructions there to add jQuery script.

second you need to define the endpoint as POST.

@app.route('/_api_call', methods=['POST'])
Sina
  • 1,055
  • 11
  • 24